SO3Engine
Delegate.h
Go to the documentation of this file.
1/*
2 FastDelegate.h v1.5, author: Don Clugston, Mar 2004
3 Efficient delegates in C++ that generate only two lines of asm code!
4 Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp
5
6 AJS: Modified for use with Hikari: trimmed out stuff we don't use.
7*/
8
9#ifndef __DELEGATE_H__
10#define __DELEGATE_H__
11
12#include <memory.h>
13#include "FlashValue.h"
14
15#define FASTDELEGATE_USESTATICFUNCTIONHACK
16#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__)
17#define FASTDLGT_ISMSVC
18#if(_MSC_VER <1300)
19#define FASTDLGT_VC6
20#pragma warning(disable:4786)
21#endif
22#endif
23#if defined(_MSC_VER) && !defined(__MWERKS__)
24#define FASTDLGT_MICROSOFT_MFP
25#if !defined(__VECTOR_C)
26#define FASTDLGT_HASINHERITANCE_KEYWORDS
27#endif
28#endif
29#ifdef __GNUC__
30
31#define FASTDELEGATE_GCC_BUG_8271
32#endif
33namespace Hikari {
34namespace Impl {
35namespace fastdelegate {
36 namespace detail {
37 template <class OutputClass, class InputClass>
38 inline OutputClass implicit_cast(InputClass input){
39 return input;
40 }
41 template <class OutputClass, class InputClass>
43 OutputClass out;
44 InputClass in;
45 };
46 template <class OutputClass, class InputClass>
47 inline OutputClass horrible_cast(const InputClass input){
49
50 typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u)
51 && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1];
52 u.in = input;
53 return u.out;
54 }
55#define FASTDELEGATEDECLARE(CLASSNAME) class CLASSNAME;
56#ifdef __MEDIUM__
57#undef FASTDELEGATE_USESTATICFUNCTIONHACK
58#endif
59#ifdef FASTDLGT_VC6
60 typedef const void * DefaultVoid;
61#else
62 typedef void DefaultVoid;
63#endif
64 template <class T>
65 struct DefaultVoidToVoid { typedef T type; };
66 template <>
67 struct DefaultVoidToVoid<DefaultVoid> { typedef void type; };
68 template <class T>
69 struct VoidToDefaultVoid { typedef T type; };
70 template <>
71 struct VoidToDefaultVoid<void> { typedef DefaultVoid type; };
72#ifdef FASTDLGT_MICROSOFT_MFP
73#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS
74
75 class __single_inheritance GenericClass;
76#endif
77 class GenericClass {};
78#else
79 class GenericClass;
80#endif
81 const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)());
82 template <int N>
84 template <class X, class XFuncType, class GenericMemFuncType>
85 inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind,
86 GenericMemFuncType &bound_func) {
87
88
89 typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100];
90 return 0;
91 }
92 };
93 template <>
95 template <class X, class XFuncType, class GenericMemFuncType>
96 inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind,
97 GenericMemFuncType &bound_func) {
98#if defined __DMC__
99
100
101
103#else
104 bound_func = reinterpret_cast<GenericMemFuncType>(function_to_bind);
105#endif
106 return reinterpret_cast<GenericClass *>(pthis);
107 }
108 };
109#ifdef FASTDLGT_MICROSOFT_MFP
110 template<>
112 template <class X, class XFuncType, class GenericMemFuncType>
114 GenericMemFuncType &bound_func) {
115
116
117 union {
118 XFuncType func;
119 struct {
120 GenericMemFuncType funcaddress;
121 int delta;
122 }s;
123 } u;
124
125 typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1];
126 u.func = function_to_bind;
127 bound_func = u.s.funcaddress;
128 return reinterpret_cast<GenericClass *>(reinterpret_cast<char *>(pthis) + u.s.delta);
129 }
130 };
136 struct GenericVirtualClass : virtual public GenericClass
137 {
139 GenericVirtualClass * GetThis() { return this; }
140 };
141 template <>
143 {
144 template <class X, class XFuncType, class GenericMemFuncType>
146 GenericMemFuncType &bound_func) {
147 union {
148 XFuncType func;
149 GenericClass* (X::*ProbeFunc)();
151 } u;
152 u.func = function_to_bind;
153 bound_func = reinterpret_cast<GenericMemFuncType>(u.s.codeptr);
154 union {
157 } u2;
158
159 typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)
160 && sizeof(function_to_bind)==sizeof(u.ProbeFunc)
161 && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1];
163 u.s.codeptr = u2.s.codeptr;
164 return (pthis->*u.ProbeFunc)();
165 }
166 };
167#if(_MSC_VER <1300)
168 template <>
170 {
171 template <class X, class XFuncType, class GenericMemFuncType>
173 GenericMemFuncType &bound_func) {
174
175 typedef char ERROR_VC6CompilerBug[-100];
176 return 0;
177 }
178 };
179#else
180 template <>
181 struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(int) >
182 {
183 template <class X, class XFuncType, class GenericMemFuncType>
185 GenericMemFuncType &bound_func) {
186
187
188 union {
189 XFuncType func;
190
191
192 struct {
193 GenericMemFuncType m_funcaddress;
194 int delta;
195 int vtordisp;
196 int vtable_index;
197 } s;
198 } u;
199
200 typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1];
201 u.func = function_to_bind;
202 bound_func = u.s.funcaddress;
203 int virtual_delta = 0;
204 if(u.s.vtable_index) {
205
206
207 const int * vtable = *reinterpret_cast<const int *const*>(
208 reinterpret_cast<const char *>(pthis) + u.s.vtordisp );
209
210 virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>(
211 reinterpret_cast<const char *>(vtable) + u.s.vtable_index);
212 }
213 return reinterpret_cast<GenericClass *>(
214 reinterpret_cast<char *>(pthis) + u.s.delta + virtual_delta);
215 };
216 };
217#endif
218#endif
219 }
221 protected:
222
226#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
227 typedef void (*GenericFuncPtr)();
229#endif
230 public:
231#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
233 void clear() {
235 }
236#else
238 void clear() { m_pthis=0; m_pFunction=0; }
239#endif
240 public:
241#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
242 inline bool IsEqual (const DelegateMemento &x) const{
243
245 return false;
246
248 return false;
249 if(m_pStaticFunction!=0)
250 return m_pthis==x.m_pthis;
251 else
252 return true;
253 }
254#else
255 inline bool IsEqual (const DelegateMemento &x) const{
256 return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction;
257 }
258#endif
259
260 inline bool IsLess(const DelegateMemento &right) const {
261
262#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
263 if(m_pStaticFunction !=0 || right.m_pStaticFunction!=0)
265#endif
266 if(m_pthis !=right.m_pthis) return m_pthis < right.m_pthis;
267
268
269
270 return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0;
271 }
272
273 inline bool operator ! () const
274 { return m_pthis==0 && m_pFunction==0; }
275 inline bool empty() const
276 { return m_pthis==0 && m_pFunction==0; }
277 public:
279 SetMementoFrom(right);
280 return *this;
281 }
282 inline bool operator <(const DelegateMemento &right) {
283 return IsLess(right);
284 }
285 inline bool operator >(const DelegateMemento &right) {
286 return right.IsLess(*this);
287 }
290#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
292#endif
293 {}
294 protected:
295 void SetMementoFrom(const DelegateMemento &right) {
296 m_pFunction = right.m_pFunction;
297 m_pthis = right.m_pthis;
298#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
300#endif
301 }
302 };
303 namespace detail {
304 template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr>
306 public:
307
308 template < class X, class XMemFunc >
312#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
314#endif
315 }
316
317 template < class X, class XMemFunc>
320 ::Convert(const_cast<X*>(pthis), function_to_bind, m_pFunction);
321#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
323#endif
324 }
325#ifdef FASTDELEGATE_GCC_BUG_8271
326 template < class X, class XMemFunc>
329#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
331#endif
332 }
333#endif
334
335 inline GenericClass *GetClosureThis() const { return m_pthis; }
336 inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast<GenericMemFunc>(m_pFunction); }
337#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
338 public:
339
340 template< class DerivedClass >
341 inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) {
343 if(m_pStaticFunction!=0) {
344
345 m_pthis=reinterpret_cast<GenericClass *>(pParent);
346 }
347 }
348
349 template < class DerivedClass, class ParentInvokerSig >
360 return reinterpret_cast<UnvoidStaticFuncPtr>(m_pStaticFunction);
361 }
362#else
363 template< class DerivedClass >
367
368 template < class DerivedClass, class ParentInvokerSig>
382
384
385 typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1];
387 }
388#endif
389
391 if(funcptr==0) return empty();
392
393
394 else return funcptr==reinterpret_cast<StaticFuncPtr>(GetStaticFunction());
395 }
396 };
397 }
398 template<class Param1, class Param2, class RetType=detail::DefaultVoid>
400 private:
401 typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
402 typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2);
403 typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2);
404 typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2);
406 ClosureType m_Closure;
407 public:
408
410
413 m_Closure.CopyFrom(this, x.m_Closure); }
414 void operator = (const FastDelegate2 &x) {
415 m_Closure.CopyFrom(this, x.m_Closure); }
416 bool operator ==(const FastDelegate2 &x) const {
417 return m_Closure.IsEqual(x.m_Closure); }
418 bool operator !=(const FastDelegate2 &x) const {
419 return !m_Closure.IsEqual(x.m_Closure); }
420 bool operator <(const FastDelegate2 &x) const {
421 return m_Closure.IsLess(x.m_Closure); }
422 bool operator >(const FastDelegate2 &x) const {
423 return x.m_Closure.IsLess(m_Closure); }
424
425 template < class X, class Y >
426 FastDelegate2(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) ) {
427 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
428 template < class X, class Y >
429 inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2)) {
430 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
431
432 template < class X, class Y >
433 FastDelegate2(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) {
434 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind); }
435 template < class X, class Y >
436 inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) {
437 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind); }
438
439
440 FastDelegate2(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) {
441 bind(function_to_bind); }
442
443 void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) {
444 bind(function_to_bind); }
445 inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2)) {
446 m_Closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction,
447 function_to_bind); }
448
449 RetType operator() (Param1 p1, Param2 p2) const {
450 return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2); }
451
452 private:
453 typedef struct SafeBoolStruct {
454 int a_data_pointer_to_this_is_0_on_buggy_compilers;
455 StaticFunctionPtr m_nonzero;
456 } UselessTypedef;
457 typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
458 public:
459 operator unspecified_bool_type() const {
460 return empty()? 0: &SafeBoolStruct::m_nonzero;
461 }
462
463 inline bool operator==(StaticFunctionPtr funcptr) {
464 return m_Closure.IsEqualToStaticFuncPtr(funcptr); }
465 inline bool operator!=(StaticFunctionPtr funcptr) {
466 return !m_Closure.IsEqualToStaticFuncPtr(funcptr); }
467 inline bool operator ! () const {
468 return !m_Closure; }
469 inline bool empty() const {
470 return !m_Closure; }
471 void clear() { m_Closure.clear();}
472
473 const DelegateMemento & GetMemento() { return m_Closure; }
474 void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
475 private:
476 RetType InvokeStaticFunction(Param1 p1, Param2 p2) const {
477 return (*(m_Closure.GetStaticFunction()))(p1, p2); }
478 };
479}
480}
481
482
483}
484#endif
if(so3win !=0)
Definition SO3SCOL.cpp:5117
bool operator>(const DelegateMemento &right)
Definition Delegate.h:285
bool IsEqual(const DelegateMemento &x) const
Definition Delegate.h:242
DelegateMemento(const DelegateMemento &right)
Definition Delegate.h:288
void(detail::GenericClass::* GenericMemFuncType)()
Definition Delegate.h:223
bool operator<(const DelegateMemento &right)
Definition Delegate.h:282
DelegateMemento & operator=(const DelegateMemento &right)
Definition Delegate.h:278
bool IsLess(const DelegateMemento &right) const
Definition Delegate.h:260
FastDelegate2(const Y *pthis, DesiredRetType(X::*function_to_bind)(Param1 p1, Param2 p2) const)
Definition Delegate.h:433
void operator=(const FastDelegate2 &x)
Definition Delegate.h:414
bool operator!=(StaticFunctionPtr funcptr)
Definition Delegate.h:465
void bind(const Y *pthis, DesiredRetType(X::*function_to_bind)(Param1 p1, Param2 p2) const)
Definition Delegate.h:436
RetType operator()(Param1 p1, Param2 p2) const
Definition Delegate.h:449
const DelegateMemento & GetMemento()
Definition Delegate.h:473
bool operator>(const FastDelegate2 &x) const
Definition Delegate.h:422
bool operator==(StaticFunctionPtr funcptr)
Definition Delegate.h:463
bool operator!=(const FastDelegate2 &x) const
Definition Delegate.h:418
bool operator==(const FastDelegate2 &x) const
Definition Delegate.h:416
FastDelegate2(Y *pthis, DesiredRetType(X::*function_to_bind)(Param1 p1, Param2 p2))
Definition Delegate.h:426
FastDelegate2(DesiredRetType(*function_to_bind)(Param1 p1, Param2 p2))
Definition Delegate.h:440
void SetMemento(const DelegateMemento &any)
Definition Delegate.h:474
void bind(DesiredRetType(*function_to_bind)(Param1 p1, Param2 p2))
Definition Delegate.h:445
bool operator<(const FastDelegate2 &x) const
Definition Delegate.h:420
FastDelegate2(const FastDelegate2 &x)
Definition Delegate.h:412
void bind(Y *pthis, DesiredRetType(X::*function_to_bind)(Param1 p1, Param2 p2))
Definition Delegate.h:429
UnvoidStaticFuncPtr GetStaticFunction() const
Definition Delegate.h:359
void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind)
Definition Delegate.h:318
void bindmemfunc(X *pthis, XMemFunc function_to_bind)
Definition Delegate.h:309
void CopyFrom(DerivedClass *pParent, const DelegateMemento &right)
Definition Delegate.h:364
void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, StaticFuncPtr function_to_bind)
Definition Delegate.h:350
void bindmemfunc(const X *pthis, XMemFunc function_to_bind)
Definition Delegate.h:327
bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr)
Definition Delegate.h:390
void CopyFrom(DerivedClass *pParent, const DelegateMemento &x)
Definition Delegate.h:341
OutputClass horrible_cast(const InputClass input)
Definition Delegate.h:47
OutputClass implicit_cast(InputClass input)
Definition Delegate.h:38
GenericVirtualClass *(GenericVirtualClass::* ProbePtrType)()
Definition Delegate.h:138
static GenericClass * Convert(X *pthis, XFuncType function_to_bind, GenericMemFuncType &bound_func)
Definition Delegate.h:172
static GenericClass * Convert(X *pthis, XFuncType function_to_bind, GenericMemFuncType &bound_func)
Definition Delegate.h:113
static GenericClass * Convert(X *pthis, XFuncType function_to_bind, GenericMemFuncType &bound_func)
Definition Delegate.h:145
static GenericClass * Convert(X *pthis, XFuncType function_to_bind, GenericMemFuncType &bound_func)
Definition Delegate.h:96
static GenericClass * Convert(X *pthis, XFuncType function_to_bind, GenericMemFuncType &bound_func)
Definition Delegate.h:85