etqw-sdk/source/idlib/Callable.h
2008-05-29 00:00:00 +00:00

443 lines
11 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __CALLABLE_H__
#define __CALLABLE_H__
namespace sdFunctions {
class sdEmptyType {};
/*
============
sdBinderMember0
============
*/
extern const char sdBinderMember0_Identifier[];
template< class RetType, class T, class Func, class T1 = sdEmptyType, class T2 = sdEmptyType, class T3 = sdEmptyType >
class sdBinderMember0 /*:
public sdPoolAllocator< sdBinderMember0, sdBinderMember0_Identifier > */{
public:
sdBinderMember0() : obj( NULL ) {}
sdBinderMember0( Func func_, T* obj_ ) : obj( obj_ ) { function = func_; }
RetType operator()() { return ((*obj).*function)(); }
RetType operator()( T1 arg1) { return ((*obj).*function)( arg1 ); }
RetType operator()( T1 arg1, T2 arg2 ) { return ((*obj).*function)( arg1, arg2 ); }
RetType operator()( T1 arg1, T2 arg2, T3 arg3 ) { return ((*obj).*function)( arg1, arg2, arg3 ); }
private:
Func function;
T* obj;
};
/*
============
sdBinderMember0
============
*/
template< class RetType, class T1, class T2, class T3, class T, class Func >
ID_INLINE sdBinderMember0< RetType, T, Func, T1, T2, T3 > sdBindMem0( Func func, T* obj ) { return sdBinderMember0< RetType, T, Func, T1, T2, T3 >( func, obj ); }
/*
============
sdBinderMember1
============
*/
extern const char sdBinderMember1_Identifier[];
template< class RetType, class T, class Func, class T1 = sdEmptyType, class T2 = sdEmptyType, class T3 = sdEmptyType >
class sdBinderMember1 /*:
public sdPoolAllocator< sdBinderMember1, sdBinderMember1_Identifier > */ {
public:
sdBinderMember1() : obj( NULL ) {}
sdBinderMember1( Func func_, T* obj_, T1 arg1_ ) : arg1( arg1_ ), obj( obj_ ) { function = func_; }
RetType operator()() { return ((*obj).*function)( arg1 ); }
RetType operator()( T2 arg2 ) { return ((*obj).*function)( arg1, arg2 ); }
RetType operator()( T2 arg2, T3 arg3 ) { return ((*obj).*function)( arg1, arg2, arg3 ); }
private:
T1 arg1;
Func function;
T* obj;
};
/*
============
sdBinderMember1
============
*/
template< class RetType, class T1, class T2, class T3, class T, class Func >
ID_INLINE sdBinderMember1< RetType, T, Func, T1, T2, T3 > sdBindMem1( Func func, T* obj, T1 arg1 ) { return sdBinderMember1< RetType, T, Func, T1, T2, T3 >( func, obj, arg1 ); }
/*
============
sdCallable
============
*/
/*
============
sdCallableBase0
============
*/
template< class Ret >
class sdCallableBase0 {
public:
virtual ~sdCallableBase0() {}
virtual Ret operator()() const = 0;
virtual sdCallableBase0< Ret >* Clone() const = 0;
};
/*
============
sdCallableBase1
============
*/
template< class Ret, class T1 >
class sdCallableBase1 {
public:
virtual ~sdCallableBase1() {}
virtual Ret operator()( T1 arg1 ) const = 0;
virtual sdCallableBase1< Ret, T1 >* Clone() const = 0;
};
/*
============
sdCallableBase2
============
*/
template< class Ret, class T1, class T2 >
class sdCallableBase2 {
public:
virtual ~sdCallableBase2() {}
virtual Ret operator()( T1 arg1, T2 arg2 ) const = 0;
virtual sdCallableBase2< Ret, T1, T2 >* Clone() const = 0;
};
/*
============
sdCallableBase3
============
*/
template< class Ret, class T1, class T2, class T3 >
class sdCallableBase3 {
public:
virtual ~sdCallableBase3() {}
virtual Ret operator()( T1 arg1, T2 arg2, T3 arg3 ) const = 0;
virtual sdCallableBase3< Ret, T1, T2, T3 >* Clone() const = 0;
};
/*
============
sdCallableCaller0
============
*/
extern const char sdCallableCaller0_Identifier[];
template< class Func, class Ret >
class sdCallableCaller0 :
public sdCallableBase0< Ret >/*,
public sdPoolAllocator< sdCallableCaller0< Func, Ret >, sdCallableCaller0_Identifier > */{
public:
sdCallableCaller0( Func f ) : function( f ) {}
virtual ~sdCallableCaller0() {}
mutable Func function;
virtual Ret operator()() const { return function(); }
virtual sdCallableBase0< Ret >* Clone() const { return new sdCallableCaller0( function ); }
};
/*
============
sdCallableCaller1
============
*/
template< class Func = sdEmptyType, class R = sdEmptyType, class T1 = sdEmptyType >
class sdCallableCaller1;
extern const char sdCallableCaller1_Identifier[];
template< class Func, class Ret, class T1 >
class sdCallableCaller1 :
public sdCallableBase1< Ret, T1 >/*,
public sdPoolAllocator< sdCallableCaller1< Func, Ret, T1 >, sdCallableCaller1_Identifier > */{
public:
sdCallableCaller1( Func f ) : function( f ) {}
virtual ~sdCallableCaller1() {}
mutable Func function;
virtual Ret operator()( T1 arg1 ) const { return function( arg1 ); }
virtual sdCallableBase1< Ret, T1 >* Clone() const { return new sdCallableCaller1( function ); }
};
template< class Func = sdEmptyType, class R = sdEmptyType, class T1 = sdEmptyType, class T2 = sdEmptyType >
class sdCallableCaller2;
/*
============
sdCallableCaller2
============
*/
extern const char sdCallableCaller2_Identifier[];
template< class Func, class Ret, class T1, class T2 >
class sdCallableCaller2 :
public sdCallableBase2< Ret, T1, T2 >/*,
public sdPoolAllocator< sdCallableCaller2< Func, Ret, T1, T2 >, sdCallableCaller2_Identifier >*/ {
public:
sdCallableCaller2( Func f ) : function( f ) {}
virtual ~sdCallableCaller2() {}
mutable Func function;
virtual Ret operator()( T1 arg1, T2 arg2 ) const { return function( arg1, arg2 ); }
virtual sdCallableBase2< Ret, T1, T2 >* Clone() const { return new sdCallableCaller2( function ); }
};
template< class Func = sdEmptyType, class R = sdEmptyType, class T1 = sdEmptyType, class T2 = sdEmptyType , class T3 = sdEmptyType >
class sdCallableCaller3;
/*
============
sdCallableCaller3
============
*/
extern const char sdCallableCaller3_Identifier[];
template< class Func, class Ret, class T1, class T2, class T3 >
class sdCallableCaller3 :
public sdCallableBase3< Ret, T1, T2, T3 >/*,
public sdPoolAllocator< sdCallableCaller3< Func, Ret, T1, T2, T3 >, sdCallableCaller3_Identifier > */{
public:
sdCallableCaller3( Func f ) : function( f ) {}
virtual ~sdCallableCaller3() {}
mutable Func function;
virtual Ret operator()( T1 arg1, T2 arg2, T3 arg3 ) const { return function( arg1, arg2, arg3 ); }
virtual sdCallableBase3< Ret, T1, T2, T3 >* Clone() const { return new sdCallableCaller3( function ); }
};
/*
============
sdCallable
============
*/
template< class Ret, class T1 = sdEmptyType, class T2 = sdEmptyType, class T3 = sdEmptyType >
class sdCallable {};
extern const char sdCallableNoParms_Identifier[];
template< class Ret >
class sdCallable< Ret() > /*:
public sdPoolAllocator< sdCallable< Ret() >, sdCallableNoParms_Identifier > */{
public:
sdCallable() : function( NULL ) {}
~sdCallable() { Release(); }
template< class Func >
sdCallable( Func f ) : function( NULL ) {
function = new sdCallableCaller0< Func, Ret >( f );
}
sdCallable& operator=( const sdCallable& f ) {
Release();
if( f.function ) {
function = f.function->Clone();
}
return *this;
}
sdCallable( const sdCallable& rhs ) : function( NULL ) {
*this = rhs;
}
Ret operator()() const {
return (*function)();
}
void Release() {
delete function;
function = NULL;
}
bool IsValid() const { return function != NULL; }
private:
mutable sdCallableBase0< Ret >* function;
};
/*
============
sdCallable< Ret( T1 ) >
============
*/
extern const char sdCallableOneParm_Identifier[];
template< class Ret, class T1 >
class sdCallable< Ret( T1 ) > /*:
public sdPoolAllocator< sdCallable< Ret( T1 ) >, sdCallableOneParm_Identifier > */{
public:
sdCallable() : function( NULL ) {}
~sdCallable() { Release(); }
template< class Func >
sdCallable( Func f ) : function( NULL ) {
function = new sdCallableCaller1< Func, Ret, T1 >( f );
}
sdCallable& operator=( const sdCallable& f ) {
Release();
if( f.function ) {
function = f.function->Clone();
}
return *this;
}
sdCallable( const sdCallable& rhs ) : function( NULL ) {
*this = rhs;
}
Ret operator()( T1 arg1 ) const {
return (*function)( arg1 );
}
void Release() {
delete function;
function = NULL;
}
bool IsValid() const { return function != NULL; }
private:
mutable sdCallableBase1< Ret, T1 >* function;
};
/*
============
sdCallable< Ret( T1, T2 ) >
============
*/
extern const char sdCallableTwoParms_Identifier[];
template< class Ret, class T1, class T2 >
class sdCallable< Ret( T1, T2 ) > /*:
public sdPoolAllocator< sdCallable< Ret( T1, T2 ) >, sdCallableTwoParms_Identifier > */{
public:
sdCallable() : function( NULL ) {}
~sdCallable() { Release(); }
template< class Func >
sdCallable( Func f ) : function( NULL ) {
function = new sdCallableCaller2< Func, Ret, T1, T2 >( f );
}
sdCallable& operator=( const sdCallable& f ) {
Release();
if( f.function ) {
function = f.function->Clone();
}
return *this;
}
sdCallable( const sdCallable& rhs ) : function( NULL ) {
*this = rhs;
}
Ret operator()( T1 arg1, T2 arg2 ) const {
return (*function)( arg1, arg2 );
}
void Release() {
delete function;
function = NULL;
}
bool IsValid() const { return function != NULL; }
private:
mutable sdCallableBase2< Ret, T1, T2 >* function;
};
/*
============
sdCallable< Ret( T1, T2, T3 ) >
============
*/
extern const char sdCallableThreeParms_Identifier[];
template< class Ret, class T1, class T2, class T3 >
class sdCallable< Ret( T1, T2, T3 ) > /*:
public sdPoolAllocator< sdCallable< Ret( T1, T2, T3 ) >, sdCallableThreeParms_Identifier > */{
public:
sdCallable() : function( NULL ) {}
~sdCallable() { Release(); }
template< class Func >
sdCallable( Func f ) : function( NULL ) {
function = new sdCallableCaller3< Func, Ret, T1, T2, T3 >( f );
}
sdCallable& operator=( const sdCallable& f ) {
Release();
if( f.function ) {
function = f.function->Clone();
}
return *this;
}
sdCallable( const sdCallable& rhs ) : function( NULL ) {
*this = rhs;
}
Ret operator()( T1 arg1, T2 arg2, T3 arg3 ) const {
return (*function)( arg1, arg2, arg3 );
}
void Release() {
delete function;
function = NULL;
}
bool IsValid() const { return function != NULL; }
private:
mutable sdCallableBase3< Ret, T1, T2, T3 >* function;
};
// jrad - from boost...keep msvc from stripping const by indirecting like mad
// we don't seem to need this unless we want to extract the type back out...which we don't :)
// if we ever do, we need to change the &t in the sdReferenceWrapper constructor to addressof( t )
/*
template< typename T > struct remove_reference { typedef T type; };
template <typename T>
struct add_pointer
{
typedef typename remove_reference< T >::type no_ref_type;
typedef no_ref_type* type;
};
template <typename T> typename
add_pointer< T >::type addressof( T& t ) {
return reinterpret_cast< T* >( &const_cast< char& >( reinterpret_cast< const volatile char & >( t )));
}
*/
template< class T >
class sdReferenceWrapper {
public:
explicit sdReferenceWrapper( T& t) : _t( &t /* addressof( t ) */ ) {}
operator T&() const { return *_t; }
private:
T* _t;
};
template< class T >
ID_INLINE sdReferenceWrapper< T > sdRef( T& t ) { return sdReferenceWrapper< T >( t ); }
template< class T >
ID_INLINE sdReferenceWrapper< T const > const sdCRef( T const & t ) { return sdReferenceWrapper< T const >( t ); }
}// namespace sdCallable
#endif // __CALLABLE_H__