mame/src/emu/delegate.h

1210 lines
42 KiB
C++

/***************************************************************************
delegate.h
Templates and classes to enable delegates for callbacks.
****************************************************************************
Copyright Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
****************************************************************************
There are many implementations of delegate-like functionality for
C++ code, but none of them is a perfect drop-in fit for use in MAME.
In order to be useful in MAME, we need the following properties:
* No significant overhead; we want to use these for memory
accessors, and memory accessor overhead is already the dominant
performance aspect for most drivers.
* Existing static functions need to be bound with an additional
pointer parameter as the first argument. All existing
implementations that allow static function binding assume the
same signature as the member functions.
* We must be able to bind the function separately from the
object. This is to allow configurations to bind functions
before the objects are created.
Thus, the implementations below are based on existing works but are
really a new implementation that is specific to MAME.
--------------------------------------------------------------------
The "compatible" version of delegates is based on an implementation
from Sergey Ryazanov, found here:
http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx
These delegates essentially generate a templated static stub function
for each target function. The static function takes the first
parameter, uses it as the object pointer, and calls through the
member function. For static functions, the stub is compatible with
the signature of a static function, so we just set the stub directly.
Pros:
* should work with any modern compiler
* static bindings are just as fast as direct calls
Cons:
* lots of little stub functions generated
* double-hops on member function calls means more overhead
* calling through stub functions repackages parameters
--------------------------------------------------------------------
The "internal" version of delegates makes use of the internal
structure of member function pointers in order to convert them at
binding time into simple static function pointers. This only works
on platforms where object->func(p1, p2) is equivalent in calling
convention to func(object, p1, p2).
Most of the information on how this works comes from Don Clugston
in this article:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
Pros:
* as fast as a standard function call in static and member cases
* no stub functions or double-hops needed
Cons:
* requires internal knowledge of the member function pointer
* only works for GCC (for now; MSVC info is also readily available)
***************************************************************************/
#pragma once
#ifndef __DELEGATE_H__
#define __DELEGATE_H__
//**************************************************************************
// MACROS
//**************************************************************************
// types of delegates supported
#define DELEGATE_TYPE_COMPATIBLE 0
#define DELEGATE_TYPE_INTERNAL 1
// select which one we will be using
#if defined(__GNUC__)
#define USE_DELEGATE_TYPE DELEGATE_TYPE_INTERNAL
#else
#define USE_DELEGATE_TYPE DELEGATE_TYPE_COMPATIBLE
#endif
// nicer macros to hide the template gobblety-gook and to pass the names
#define create_member_name(_class, _member, _name) _create_member<_class, &_class::_member>(_name)
#define create_member(_class, _member) _create_member<_class, &_class::_member>(#_class "::" #_member)
#define create_static(_class, _func) _crate_static<_class, &_func>(#_func)
//**************************************************************************
// HELPER CLASSES
//**************************************************************************
// ======================> generic_class
// define a dummy generic class that is just straight single-inheritance
#ifdef _MSC_VER
class __single_inheritance generic_class;
class delegate_generic_class { };
#else
class delegate_generic_class;
#endif
// ======================> bindable_object
// define a bindable_object base class that must be at the root of any object
// hierarchy which intends to do late binding
class bindable_object
{
public:
// virtual destructor to ensure this is a polymorphic class
bindable_object();
virtual ~bindable_object();
};
// define a deferred cast helper function that does a proper dynamic_cast
// from a bindable_object to the target class, and returns a delegate_generic_class
template<class _TargetClass>
static delegate_generic_class *deferred_cast(bindable_object &object)
{
return reinterpret_cast<delegate_generic_class *>(dynamic_cast<_TargetClass *>(&object));
}
// we store pointers to these deferred casting helpers, so make a friendly type for it
typedef delegate_generic_class *(*deferred_cast_func)(bindable_object &object);
// ======================> delegate_base
// simple base class for all delegates to derive from; it is explicitly
// polymorphic so that a delegate_base * can be used as a lowest-common
// denominator, and then downcast to the appropriate type with proper
// type checking
class delegate_base
{
public:
delegate_base(deferred_cast_func caster, const char *name)
: m_caster(caster),
m_name(name) { }
virtual ~delegate_base() { }
// getters
bool isnull() const { return (m_caster == NULL); }
bool valid_target(bindable_object &object) const { return ((*m_caster)(object) != NULL); }
const char *name() const { return m_name; }
protected:
deferred_cast_func m_caster; // pointer to helper function that does the cast
const char * m_name; // name string
};
//**************************************************************************
// COMPATIBLE DELEGATES
//**************************************************************************
#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE)
// ======================> proto_delegate_0param
template<typename _ReturnType>
class proto_delegate_0param : public delegate_base
{
protected:
// pointer to a static version of the function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *);
public:
// constructors
proto_delegate_0param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function) { }
proto_delegate_0param(const proto_delegate_0param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)()>
static proto_delegate_0param _create_member(const char *name = NULL)
{
return proto_delegate_0param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *)>
static proto_delegate_0param _create_static(const char *name = NULL)
{
return proto_delegate_0param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_0param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster);
}
protected:
// helper stub that calls the member function
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)()>
static _ReturnType method_stub(delegate_generic_class *object_ptr)
{
_FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
return (p->*_FunctionPtr)();
}
// internal state
static_func m_function; // pointer to the stub or static function
};
// ======================> delegate_0param
template<typename _ReturnType>
class delegate_0param : public proto_delegate_0param<_ReturnType>
{
typedef proto_delegate_0param<_ReturnType> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
public:
// constructors
delegate_0param()
: m_object(NULL) { }
delegate_0param(proto_base proto)
: proto_delegate_0param<_ReturnType>(proto),
m_object(NULL) { }
delegate_0param(proto_base proto, bindable_object &object)
: proto_delegate_0param<_ReturnType>(proto),
m_object((*m_caster)(object)) { }
// bind the actual object
void bind(bindable_object &object) { m_object = (*m_caster)(object); }
// call the function
_ReturnType operator()() const { return (*m_function)(m_object); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_0param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_1param
template<typename _ReturnType, typename _P1Type>
class proto_delegate_1param : public delegate_base
{
protected:
// pointer to a static version of the function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type);
public:
// constructors
proto_delegate_1param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function) { }
proto_delegate_1param(const proto_delegate_1param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type)>
static proto_delegate_1param _create_member(const char *name = NULL)
{
return proto_delegate_1param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type)>
static proto_delegate_1param _create_static(const char *name = NULL)
{
return proto_delegate_1param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_1param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster);
}
protected:
// helper stub that calls the member function
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type)>
static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1)
{
_FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
return (p->*_FunctionPtr)(p1);
}
// internal state
static_func m_function; // pointer to the stub or static function
};
// ======================> delegate_1param
template<typename _ReturnType, typename _P1Type>
class delegate_1param : public proto_delegate_1param<_ReturnType, _P1Type>
{
typedef proto_delegate_1param<_ReturnType, _P1Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
public:
// constructors
delegate_1param()
: m_object(NULL) { }
delegate_1param(proto_delegate_1param<_ReturnType, _P1Type> proto)
: proto_delegate_1param<_ReturnType, _P1Type>(proto),
m_object(NULL) { }
delegate_1param(proto_delegate_1param<_ReturnType, _P1Type> proto, bindable_object &object)
: proto_delegate_1param<_ReturnType, _P1Type>(proto),
m_object((*m_caster)(object)) { }
// bind the actual object
void bind(bindable_object &object) { m_object = (*m_caster)(object); }
// call the function
_ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_1param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_2param
template<typename _ReturnType, typename _P1Type, typename _P2Type>
class proto_delegate_2param : public delegate_base
{
protected:
// pointer to a static version of the function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type);
public:
// constructors
proto_delegate_2param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function) { }
proto_delegate_2param(const proto_delegate_2param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type)>
static proto_delegate_2param _create_member(const char *name = NULL)
{
return proto_delegate_2param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type)>
static proto_delegate_2param _create_static(const char *name = NULL)
{
return proto_delegate_2param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_2param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster);
}
protected:
// helper stub that calls the member function
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type)>
static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1, _P2Type p2)
{
_FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
return (p->*_FunctionPtr)(p1, p2);
}
// internal state
static_func m_function; // pointer to the stub or static function
};
// ======================> delegate_2param
template<typename _ReturnType, typename _P1Type, typename _P2Type>
class delegate_2param : public proto_delegate_2param<_ReturnType, _P1Type, _P2Type>
{
typedef proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
public:
// constructors
delegate_2param()
: m_object(NULL) { }
delegate_2param(proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto)
: proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
m_object(NULL) { }
delegate_2param(proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto, bindable_object &object)
: proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
m_object((*m_caster)(object)) { }
// bind the actual object
void bind(bindable_object &object) { m_object = (*m_caster)(object); }
// call the function
_ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_2param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_3param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
class proto_delegate_3param : public delegate_base
{
protected:
// pointer to a static version of the function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type);
public:
// constructors
proto_delegate_3param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function) { }
proto_delegate_3param(const proto_delegate_3param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type)>
static proto_delegate_3param _create_member(const char *name = NULL)
{
return proto_delegate_3param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type)>
static proto_delegate_3param _create_static(const char *name = NULL)
{
return proto_delegate_3param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_3param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster);
}
protected:
// helper stub that calls the member function
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type)>
static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1, _P2Type p2, _P3Type p3)
{
_FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
return (p->*_FunctionPtr)(p1, p2, p3);
}
// internal state
static_func m_function; // pointer to the stub or static function
};
// ======================> delegate_3param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
class delegate_3param : public proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>
{
typedef proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
public:
// constructors
delegate_3param()
: m_object(NULL) { }
delegate_3param(proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto)
: proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
m_object(NULL) { }
delegate_3param(proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto, bindable_object &object)
: proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
m_object((*m_caster)(object)) { }
// bind the actual object
void bind(bindable_object &object) { m_object = (*m_caster)(object); }
// call the function
_ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_3param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_4param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
class proto_delegate_4param : public delegate_base
{
protected:
// pointer to a static version of the function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type, _P4Type);
public:
// constructors
proto_delegate_4param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function) { }
proto_delegate_4param(const proto_delegate_4param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type, _P4Type)>
static proto_delegate_4param _create_member(const char *name = NULL)
{
return proto_delegate_4param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type, _P4Type)>
static proto_delegate_4param _create_static(const char *name = NULL)
{
return proto_delegate_4param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_4param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster);
}
protected:
// helper stub that calls the member function
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type, _P4Type)>
static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4)
{
_FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
return (p->*_FunctionPtr)(p1, p2, p3, p4);
}
// internal state
static_func m_function; // pointer to the stub or static function
};
// ======================> delegate_4param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
class delegate_4param : public proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>
{
typedef proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
public:
// constructors
delegate_4param()
: m_object(NULL) { }
delegate_4param(proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto)
: proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
m_object(NULL) { }
delegate_4param(proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto, bindable_object &object)
: proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
m_object((*m_caster)(object)) { }
// bind the actual object
void bind(bindable_object &object) { m_object = (*m_caster)(object); }
// call the function
_ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_4param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
#endif
//**************************************************************************
// GCC DELEGATES
//**************************************************************************
#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
// a generic function pointer type and a generic member function pointer type
typedef void (*delegate_generic_function)();
// struct describing the contents of a member function pointer
struct delegate_gcc_mfp_internal
{
union // first item can be one of two things:
{
delegate_generic_function funcptr; // if even, it's a pointer to the function
FPTR vtable_index; // if odd, it's the byte offset into the vtable
} u;
int this_delta; // delta to apply to the 'this' pointer
};
// helper function
delegate_generic_function delegate_convert_raw(delegate_generic_class *&object, delegate_gcc_mfp_internal &mfp);
// global dummy extern
extern delegate_gcc_mfp_internal delegate_gcc_mfp_null;
// ======================> proto_delegate_0param
template<typename _ReturnType>
class proto_delegate_0param : public delegate_base
{
protected:
// pointer to a static function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *);
public:
// constructors
proto_delegate_0param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function),
m_rawfunction(mfp) { }
proto_delegate_0param(const proto_delegate_0param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function),
m_rawfunction(proto.m_rawfunction) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)()>
static proto_delegate_0param _create_member(const char *name = NULL)
{
union
{
_ReturnType (_FunctionClass::*mfp)();
delegate_gcc_mfp_internal internal;
} tempunion;
tempunion.mfp = _FunctionPtr;
return proto_delegate_0param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *)>
static proto_delegate_0param _create_static(const char *name = NULL)
{
return proto_delegate_0param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_0param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
}
protected:
// internal state
static_func m_function; // generic static function pointer
delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
};
// ======================> delegate_0param
template<typename _ReturnType>
class delegate_0param : public proto_delegate_0param<_ReturnType>
{
typedef _ReturnType (*static_func)(delegate_generic_class *);
typedef proto_delegate_0param<_ReturnType> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
using proto_base::m_rawfunction;
public:
// constructors
delegate_0param()
: m_object(NULL) { }
delegate_0param(proto_base proto)
: proto_delegate_0param<_ReturnType>(proto),
m_object(NULL) { }
delegate_0param(proto_base proto, bindable_object &object)
: proto_delegate_0param<_ReturnType>(proto),
m_object(NULL) { bind(object); }
// bind the actual object
void bind(bindable_object &object)
{
m_object = (*m_caster)(object);
if (m_rawfunction.u.funcptr != NULL)
m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
}
// call the function
_ReturnType operator()() const { return (*m_function)(m_object); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_0param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_1param
template<typename _ReturnType, typename _P1Type>
class proto_delegate_1param : public delegate_base
{
protected:
// pointer to a static function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type);
public:
// constructors
proto_delegate_1param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function),
m_rawfunction(mfp) { }
proto_delegate_1param(const proto_delegate_1param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function),
m_rawfunction(proto.m_rawfunction) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type)>
static proto_delegate_1param _create_member(const char *name = NULL)
{
union
{
_ReturnType (_FunctionClass::*mfp)(_P1Type);
delegate_gcc_mfp_internal internal;
} tempunion;
tempunion.mfp = _FunctionPtr;
return proto_delegate_1param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type)>
static proto_delegate_1param _create_static(const char *name = NULL)
{
return proto_delegate_1param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_1param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
}
protected:
// internal state
static_func m_function; // generic static function pointer
delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
};
// ======================> delegate_1param
template<typename _ReturnType, typename _P1Type>
class delegate_1param : public proto_delegate_1param<_ReturnType, _P1Type>
{
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type);
typedef proto_delegate_1param<_ReturnType, _P1Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
using proto_base::m_rawfunction;
public:
// constructors
delegate_1param()
: m_object(NULL) { }
delegate_1param(proto_base proto)
: proto_delegate_1param<_ReturnType, _P1Type>(proto),
m_object(NULL) { }
delegate_1param(proto_base proto, bindable_object &object)
: proto_delegate_1param<_ReturnType, _P1Type>(proto),
m_object(NULL) { bind(object); }
// bind the actual object
void bind(bindable_object &object)
{
m_object = (*m_caster)(object);
if (m_rawfunction.u.funcptr != NULL)
m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
}
// call the function
_ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_1param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_2param
template<typename _ReturnType, typename _P1Type, typename _P2Type>
class proto_delegate_2param : public delegate_base
{
protected:
// pointer to a static function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type);
public:
// constructors
proto_delegate_2param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function),
m_rawfunction(mfp) { }
proto_delegate_2param(const proto_delegate_2param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function),
m_rawfunction(proto.m_rawfunction) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type)>
static proto_delegate_2param _create_member(const char *name = NULL)
{
union
{
_ReturnType (_FunctionClass::*mfp)(_P1Type, _P2Type);
delegate_gcc_mfp_internal internal;
} tempunion;
tempunion.mfp = _FunctionPtr;
return proto_delegate_2param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type)>
static proto_delegate_2param _create_static(const char *name = NULL)
{
return proto_delegate_2param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_2param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
}
protected:
// internal state
static_func m_function; // generic static function pointer
delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
};
// ======================> delegate_2param
template<typename _ReturnType, typename _P1Type, typename _P2Type>
class delegate_2param : public proto_delegate_2param<_ReturnType, _P1Type, _P2Type>
{
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type);
typedef proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
using proto_base::m_rawfunction;
public:
// constructors
delegate_2param()
: m_object(NULL) { }
delegate_2param(proto_base proto)
: proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
m_object(NULL) { }
delegate_2param(proto_base proto, bindable_object &object)
: proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
m_object(NULL) { bind(object); }
// bind the actual object
void bind(bindable_object &object)
{
m_object = (*m_caster)(object);
if (m_rawfunction.u.funcptr != NULL)
m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
}
// call the function
_ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_2param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_3param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
class proto_delegate_3param : public delegate_base
{
protected:
// pointer to a static function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type);
public:
// constructors
proto_delegate_3param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function),
m_rawfunction(mfp) { }
proto_delegate_3param(const proto_delegate_3param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function),
m_rawfunction(proto.m_rawfunction) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type)>
static proto_delegate_3param _create_member(const char *name = NULL)
{
union
{
_ReturnType (_FunctionClass::*mfp)(_P1Type, _P2Type, _P3Type);
delegate_gcc_mfp_internal internal;
} tempunion;
tempunion.mfp = _FunctionPtr;
return proto_delegate_3param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type)>
static proto_delegate_3param _create_static(const char *name = NULL)
{
return proto_delegate_3param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_3param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
}
protected:
// internal state
static_func m_function; // generic static function pointer
delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
};
// ======================> delegate_3param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
class delegate_3param : public proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>
{
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type);
typedef proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
using proto_base::m_rawfunction;
public:
// constructors
delegate_3param()
: m_object(NULL) { }
delegate_3param(proto_base proto)
: proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
m_object(NULL) { }
delegate_3param(proto_base proto, bindable_object &object)
: proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
m_object(NULL) { bind(object); }
// bind the actual object
void bind(bindable_object &object)
{
m_object = (*m_caster)(object);
if (m_rawfunction.u.funcptr != NULL)
m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
}
// call the function
_ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_3param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
// ======================> proto_delegate_4param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
class proto_delegate_4param : public delegate_base
{
protected:
// pointer to a static function which takes the object as a first parameter
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type, _P4Type);
public:
// constructors
proto_delegate_4param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
: delegate_base(caster, name),
m_function(function),
m_rawfunction(mfp) { }
proto_delegate_4param(const proto_delegate_4param &proto)
: delegate_base(proto.m_caster, proto.m_name),
m_function(proto.m_function),
m_rawfunction(proto.m_rawfunction) { }
// create a member function proto-delegate
template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type, _P4Type)>
static proto_delegate_4param _create_member(const char *name = NULL)
{
union
{
_ReturnType (_FunctionClass::*mfp)(_P1Type, _P2Type, _P3Type, _P4Type);
delegate_gcc_mfp_internal internal;
} tempunion;
tempunion.mfp = _FunctionPtr;
return proto_delegate_4param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
}
// create a static function proto-delegate
template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type, _P4Type)>
static proto_delegate_4param _create_static(const char *name = NULL)
{
return proto_delegate_4param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
}
// equality testing
bool operator==(const proto_delegate_4param &rhs) const
{
return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
}
protected:
// internal state
static_func m_function; // generic static function pointer
delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
};
// ======================> delegate_4param
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
class delegate_4param : public proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>
{
typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type, _P4Type);
typedef proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto_base;
using delegate_base::m_caster;
using proto_base::m_function;
using proto_base::m_rawfunction;
public:
// constructors
delegate_4param()
: m_object(NULL) { }
delegate_4param(proto_base proto)
: proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
m_object(NULL) { }
delegate_4param(proto_base proto, bindable_object &object)
: proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
m_object(NULL) { bind(object); }
// bind the actual object
void bind(bindable_object &object)
{
m_object = (*m_caster)(object);
if (m_rawfunction.u.funcptr != NULL)
m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
}
// call the function
_ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); }
// testing
bool has_object() const { return (m_object != NULL); }
bool operator==(const delegate_4param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
protected:
// internal state
delegate_generic_class *m_object; // pointer to the post-cast object
};
#endif
#endif /* __DELEGATE_H__ */