bbfunction.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #ifndef BB_FUNCTION_H
  2. #define BB_FUNCTION_H
  3. #include "bbtypes.h"
  4. //#include "bbgc.h"
  5. #include "bbdebug.h"
  6. template<class T> class bbFunction;
  7. template<class R,class...A> struct bbFunction<R(A...)>{
  8. typedef R(*F)(A...);
  9. struct FunctionRep;
  10. struct SequenceRep;
  11. template<class C> struct MethodRep;
  12. static R castErr( A... ){
  13. puts( "Null Function Error" );
  14. exit( -1 );
  15. return R();
  16. }
  17. struct Rep{
  18. int refs=0;
  19. virtual ~Rep(){
  20. }
  21. virtual R invoke( A... ){
  22. return R();
  23. }
  24. virtual bool equals( Rep *rep ){
  25. return rep==this;
  26. }
  27. virtual int compare( Rep *rhs ){
  28. if( this<rhs ) return -1;
  29. if( this>rhs ) return 1;
  30. return 0;
  31. }
  32. virtual Rep *remove( Rep *rep ){
  33. if( equals( rep ) ) return &_nullRep;
  34. return this;
  35. }
  36. virtual void gcMark(){
  37. }
  38. void *operator new( size_t size ){
  39. return bbMalloc( size );
  40. }
  41. void operator delete( void *p ){
  42. bbFree( p );
  43. }
  44. };
  45. struct FunctionRep : public Rep{
  46. F p;
  47. FunctionRep( F p ):p( p ){
  48. }
  49. virtual R invoke( A...a ){
  50. return p( a... );
  51. }
  52. virtual bool equals( Rep *rhs ){
  53. FunctionRep *t=dynamic_cast<FunctionRep*>( rhs );
  54. return t && p==t->p;
  55. }
  56. virtual int compare( Rep *rhs ){
  57. FunctionRep *t=dynamic_cast<FunctionRep*>( rhs );
  58. if( t && p==t->p ) return 0;
  59. return Rep::compare( rhs );
  60. }
  61. virtual F Cast(){
  62. return p;
  63. }
  64. };
  65. template<class C> struct MethodRep : public Rep{
  66. typedef R(C::*T)(A...);
  67. C *c;
  68. T p;
  69. MethodRep( C *c,T p ):c(c),p(p){
  70. }
  71. virtual R invoke( A...a ){
  72. return (c->*p)( a... );
  73. }
  74. virtual bool equals( Rep *rhs ){
  75. MethodRep *t=dynamic_cast<MethodRep*>( rhs );
  76. return t && c==t->c && p==t->p;
  77. }
  78. virtual int compare( Rep *rhs ){
  79. MethodRep *t=dynamic_cast<MethodRep*>( rhs );
  80. if( t && c==t->c && p==t->p ) return 0;
  81. return Rep::compare( rhs );
  82. }
  83. virtual void gcMark(){
  84. bbGCMark( c );
  85. }
  86. };
  87. struct SequenceRep : public Rep{
  88. bbFunction lhs,rhs;
  89. SequenceRep( const bbFunction &lhs,const bbFunction &rhs ):lhs( lhs ),rhs( rhs ){
  90. }
  91. virtual R invoke( A...a ){
  92. lhs( a... );
  93. return rhs( a... );
  94. }
  95. virtual Rep *remove( Rep *rep ){
  96. if( rep==this ) return &_nullRep;
  97. Rep *lhs2=lhs._rep->remove( rep );
  98. Rep *rhs2=rhs._rep->remove( rep );
  99. if( lhs2==lhs._rep && rhs2==rhs._rep ) return this;
  100. if( lhs2!=&_nullRep && rhs2 !=&_nullRep ) return new SequenceRep( lhs2,rhs2 );
  101. if( lhs2!=&_nullRep ) return lhs2;
  102. if( rhs2!=&_nullRep ) return rhs2;
  103. return &_nullRep;
  104. }
  105. virtual void gcMark(){
  106. lhs._rep->gcMark();
  107. rhs._rep->gcMark();
  108. }
  109. };
  110. Rep *_rep;
  111. static Rep _nullRep;
  112. void retain()const{
  113. ++_rep->refs;
  114. }
  115. void release(){
  116. if( !--_rep->refs && _rep!=&_nullRep ) delete _rep;
  117. }
  118. bbFunction( Rep *rep ):_rep( rep ){
  119. retain();
  120. }
  121. public:
  122. bbFunction():_rep( &_nullRep ){
  123. }
  124. bbFunction( const bbFunction &p ):_rep( p._rep ){
  125. retain();
  126. }
  127. template<class C> bbFunction( C *c,typename MethodRep<C>::T p ):_rep( new MethodRep<C>(c,p) ){
  128. retain();
  129. }
  130. bbFunction( F p ):_rep( new FunctionRep( p ) ){
  131. retain();
  132. }
  133. ~bbFunction(){
  134. release();
  135. }
  136. bbFunction &operator=( const bbFunction &p ){
  137. p.retain();
  138. release();
  139. _rep=p._rep;
  140. return *this;
  141. }
  142. bbFunction operator+( const bbFunction &rhs )const{
  143. if( _rep==&_nullRep ) return rhs;
  144. if( rhs._rep==&_nullRep ) return *this;
  145. return new SequenceRep( *this,rhs );
  146. }
  147. bbFunction operator-( const bbFunction &rhs )const{
  148. return _rep->remove( rhs._rep );
  149. }
  150. bbFunction &operator+=( const bbFunction &rhs ){
  151. *this=*this+rhs;
  152. return *this;
  153. }
  154. bbFunction &operator-=( const bbFunction &rhs ){
  155. *this=*this-rhs;
  156. return *this;
  157. }
  158. bbBool operator==( const bbFunction &rhs )const{
  159. return _rep->equals( rhs._rep );
  160. }
  161. bbBool operator!=( const bbFunction &rhs )const{
  162. return !_rep->equals( rhs._rep );
  163. }
  164. operator bbBool()const{
  165. return _rep==&_nullRep;
  166. }
  167. R operator()( A...a )const{
  168. return _rep->invoke( a... );
  169. }
  170. //cast to simple static function ptr
  171. //
  172. operator F()const{
  173. FunctionRep *t=dynamic_cast<FunctionRep*>( _rep );
  174. if( t ) return t->p;
  175. return castErr;
  176. }
  177. };
  178. template<class R,class...A> typename bbFunction<R(A...)>::Rep bbFunction<R(A...)>::_nullRep;
  179. template<class C,class R,class...A> bbFunction<R(A...)> bbMethod( C *c,R(C::*p)(A...) ){
  180. return bbFunction<R(A...)>( c,p );
  181. }
  182. template<class C,class R,class...A> bbFunction<R(A...)> bbMethod( const bbGCVar<C> &c,R(C::*p)(A...) ){
  183. return bbFunction<R(A...)>( c.get(),p );
  184. }
  185. template<class R,class...A> bbFunction<R(A...)> bbMakefunc( R(*p)(A...) ){
  186. return bbFunction<R(A...)>( p );
  187. }
  188. template<class R,class...A> void bbGCMark( const bbFunction<R(A...)> &t ){
  189. t._rep->gcMark();
  190. }
  191. template<class R,class...A> int bbCompare( const bbFunction<R(A...)> &x,const bbFunction<R(A...)> &y ){
  192. return x._rep->compare( y._rep );
  193. }
  194. template<class R,class...A> bbString bbDBType( bbFunction<R(A...)> *p ){
  195. return bbDBType<R>()+"()";
  196. }
  197. template<class R,class...A> bbString bbDBValue( bbFunction<R(A...)> *p ){
  198. return "function?????";
  199. }
  200. #endif