00001 # ifndef _PIPEMODULES_H_
00002 # define _PIPEMODULES_H_
00003
00004 # include <XVException.h>
00005 # include <XVFunctoid.h>
00006 # include "Dependency.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 class PipeException : public XVException { protected:
00017 PipeException() : XVException("Pipe Exception") {}
00018 PipeException( char * err ) : XVException(err) {} };
00019
00020
00021 class BrokenPipe : public PipeException { public:
00022 BrokenPipe() : PipeException("Broken Pipe") {}
00023 BrokenPipe( char * err ) : PipeException(err) {} };
00024
00025
00026 class UninitPipe : public PipeException { public:
00027 UninitPipe() : PipeException("Uninitialized Pipe") {}
00028 UninitPipe( char * err ) : PipeException(err) {} };
00029
00030
00031 class RedefPipe : public PipeException { public:
00032 RedefPipe() : PipeException("Redefined Pipe") {}
00033 RedefPipe( char * err ) : PipeException(err) {} };
00034
00035
00036
00037
00038
00039
00040 template<class T> class Pipe;
00041
00042 template<class T>
00043 class PipeModule : protected DependencyUnit {
00044 struct Update {
00045 int fc ;
00046 T * addr ;
00047 Update * next ;
00048 Update( int fc, T * addr, Update * next=0 ) :
00049 fc(fc), addr(addr), next(next) {}
00050 ~Update() { delete next ; }
00051 } * head ;
00052
00053 protected:
00054 void addUpdate( int fc, T * addr ) { head = new Update( fc, addr, head ); }
00055 void update( int fc, const T& data ) {
00056 Update ** p ;
00057 int k = 0 ;
00058 for( p = &head ; *p ; ) {
00059 if( (*p)->fc == fc ) {
00060 *((*p)->addr) = data ;
00061 }
00062 if( fc - (*p)->fc < 0 ) {
00063 p = &((*p)->next);
00064 }else {
00065 Update * temp = *p ;
00066 *p = temp->next ;
00067 temp->next = 0 ;
00068 delete temp ;
00069 }
00070 }
00071 }
00072
00073 protected:
00074 int frame_count ;
00075
00076 T value ;
00077
00078 protected:
00079 # ifndef NDEBUG
00080 inline void check( bool statement ) const
00081 { if( !statement ) throw UninitPipe(); }
00082 # else
00083 inline void check( bool ) const {}
00084 # endif
00085
00086 protected:
00087
00088 void setDependency(void) {}
00089 PipeModule<T> * duplicate(void) const { return new PipeModule<T>(*this); }
00090
00091 public:
00092 typedef T ReturnType ;
00093 typedef Pipe<T> ResultType ;
00094
00095 PipeModule() : head(0), frame_count(-1) { setDependency(); }
00096 PipeModule( const PipeModule<T>& p ) : DependencyUnit(p),
00097 head(0), frame_count(p.frame_count), value(p.value)
00098 { setDependency(); }
00099 PipeModule( const T& x ) :
00100 head(0), frame_count(-1), value(x) { setDependency(); }
00101
00102 virtual T current_value(void) const { return value ; }
00103
00104 virtual T compute_local_fn(int) { return value; }
00105
00106 virtual T get_value( int fcin ) {
00107 if( fcin != frame_count ) {
00108 value = compute_local_fn( fcin );
00109 frame_count = fcin ;
00110 update( frame_count, value );
00111 }
00112 return value ;
00113 }
00114 virtual void get_value( int fcin, T * ptr ) {
00115 if( fcin != frame_count ) {
00116 addUpdate( fcin, ptr );
00117 }else {
00118 *ptr = value ;
00119 }
00120 }
00121
00122 virtual T next_value() {
00123 return get_value( frame_count+1 );
00124 }
00125 };
00126
00127
00128
00129
00130 template <class T>
00131 class Pipe : public PipeModule<T> {
00132 protected:
00133 PipeModule<T> ** module ;
00134
00135 protected:
00136 void setDependency(void) { addDependency((DependencyUnit**)module); }
00137 Pipe<T> * duplicate(void) const { return new Pipe<T>(*module); }
00138
00139
00140 inline void check(void) const { PipeModule<T>::check( *module ); }
00141
00142 public:
00143 Pipe() : module(new (PipeModule<T> *)(0)) { setDependency(); }
00144
00145 Pipe( const Pipe& p ) : PipeModule<T>(p), module(p.module)
00146 { setDependency(); }
00147
00148
00149 Pipe( const T& x ) : module(new (PipeModule<T> *)(new PipeModule<T>(x)))
00150 { setDependency(); }
00151
00152
00153 Pipe( PipeModule<T> *v ) : module(new (PipeModule<T> *)(v))
00154 { setDependency(); }
00155
00156 Pipe<T>& operator = ( const Pipe<T>& p )
00157 {
00158 if( &p != this ) {
00159 if( *module ) throw RedefPipe();
00160
00161 *module = new Pipe<T>(p) ;
00162 }
00163 return *this ;
00164 }
00165
00166 T current_value(void) const { check(); return (*module)->current_value() ; }
00167 T get_value( int fcin ) { check(); return (*module)->get_value(fcin); }
00168 void get_value( int fcin, T * ptr )
00169 { check(); return (*module)->get_value(fcin, ptr); }
00170 T next_value() { check(); return (*module)->next_value(); }
00171 PipeModule<T>* operator ->() { check(); return *module ; }
00172
00173 void run()
00174 { check(); try{ for(;;) (*module)->next_value(); } catch(BrokenPipe) {} }
00175 void run( unsigned int n )
00176 {
00177 check();
00178 try{
00179 for( int i = 0 ; i < n ; i ++ ) {
00180 (*module)->next_value();
00181 }
00182 }catch(BrokenPipe) {}
00183 }
00184
00185 template<class Tout, class Tin1> friend class PipeFun1 ;
00186 template<class Tout, class Tin1, class Tin2> friend class PipeFun2 ;
00187 };
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 template <class Tout>
00211 class PipeLift0 : public PipeModule<Tout>
00212 {
00213 public:
00214
00215 PipeLift0() : PipeModule<Tout>() {};
00216 PipeLift0( const PipeLift0<Tout>& p ) : PipeModule<Tout>(p) {};
00217
00218 virtual Pipe<Tout> operator()(void) const = 0;
00219 };
00220
00221 template <class Tout,class Tin>
00222 class PipeLift1 : public PipeModule<Tout>
00223 {
00224 public:
00225
00226 PipeLift1() : PipeModule<Tout>() {};
00227 PipeLift1( const PipeLift1<Tout,Tin>& p ) : PipeModule<Tout>(p) {};
00228
00229 virtual Pipe<Tout> operator()(const Pipe<Tin>&) const = 0;
00230 };
00231
00232 template <class Tout,class Tin1, class Tin2>
00233 class PipeLift2 : public PipeModule<Tout>
00234 {
00235 public:
00236
00237 PipeLift2() : PipeModule<Tout>() {};
00238 PipeLift2( const PipeLift2<Tout,Tin1,Tin2>& p ) : PipeModule<Tout>(p) {};
00239
00240
00241 };
00242
00243
00244 template <class Tout, class Tin1, class Tin2, class Tin3>
00245 class PipeLift3 : public PipeModule<Tout>
00246 {
00247 public:
00248
00249 PipeLift3() : PipeModule<Tout>() {};
00250 PipeLift3( const PipeLift3<Tout,Tin1,Tin2,Tin3>& p ) : PipeModule<Tout>(p) {};
00251
00252 virtual Pipe<Tout> operator()(const Pipe<Tin1>&,const Pipe<Tin2>&, const Pipe<Tin3> &) const = 0;
00253 };
00254
00255
00256
00257
00258 template<class Tout>
00259 class PipeModuleLift0 : public PipeLift0<Tout> {
00260 typedef PipeModuleLift0<Tout> ThisType ;
00261 typedef PipeLift0<Tout> BaseType ;
00262 protected:
00263 typedef Tout (*Lift0Type)(void);
00264 Lift0Type fn ;
00265
00266 protected:
00267
00268 void setDependency(void) {}
00269 ThisType * duplicate(void) const { return new ThisType(*this);}
00270
00271 protected:
00272
00273 inline void check(void) { PipeModule<Tout>::check( fn ); }
00274
00275 public:
00276
00277 PipeModuleLift0( Lift0Type fnin ) : fn(fnin) { setDependency(); }
00278 PipeModuleLift0( const ThisType& p ) : BaseType(p),
00279 fn(p.fn) { setDependency(); }
00280
00281 operator Pipe<Tout> () const { return Pipe<Tout>(dupilcate()); }
00282
00283 Pipe<Tout> operator ()(void) const { return Pipe<Tout>(duplicate()); }
00284
00285 Tout compute_local_fn( int fc ) { check(); return fn(); }
00286 };
00287
00288
00289
00290
00291
00292 template<class Tout>
00293 inline Pipe<Tout> liftP( Tout (*fn)(void) ) {
00294 return Pipe<Tout>(new PipeModuleLift0<Tout>(fn));
00295 }
00296
00297 template <class Tout, class Tin1, class Fn>
00298 class PipeModuleLift1 : public PipeLift1<Tout,Tin1> {
00299 typedef PipeModuleLift1<Tout,Tin1,Fn> ThisType ;
00300 typedef PipeLift1<Tout,Tin1> BaseType ;
00301 protected:
00302 Fn fn ;
00303 Pipe<Tin1> *pred1 ;
00304
00305 protected:
00306
00307 void setDependency(void) { addDependency((DependencyUnit**)&pred1); }
00308 ThisType * duplicate(void) const { return new ThisType(*this); }
00309
00310 inline void check(void)
00311 { PipeModule<Tout>::check( (bool)fn && pred1 ); }
00312
00313 public:
00314
00315 PipeModuleLift1( Fn fnin ) : fn(fnin), pred1(0) { setDependency(); }
00316 PipeModuleLift1( const ThisType& p ) :
00317 BaseType(p), fn(p.fn), pred1(p.pred1) { setDependency(); }
00318
00319 Pipe<Tout> operator ()( const Pipe<Tin1>& x ) const
00320 {
00321 ThisType *p = duplicate();
00322 p->pred1 = new Pipe<Tin1>(x) ;
00323 return Pipe<Tout>(p) ;
00324 }
00325
00326 Tout compute_local_fn( int fc )
00327 { check(); return fn(pred1->get_value(fc)); }
00328 };
00329
00330 template<class Tout, class Tin1>
00331 class PipeModuleLift1Types {
00332 public:
00333 typedef PipeModuleLift1<Tout,Tin1,Tout (*)(Tin1)> Val;
00334 typedef PipeModuleLift1<Tout,Tin1,Tout (*)(const Tin1&)> Ref;
00335 };
00336
00337 template<class Tout, class Tin1>
00338 inline PipeModuleLift1<Tout, Tin1, Tout (*)(Tin1)>
00339 liftP( Tout (*fn)(Tin1) ) {
00340 return PipeModuleLift1<Tout,Tin1,Tout (*)(Tin1)>(fn);
00341 }
00342 template<class Tout, class Tin1>
00343 inline PipeModuleLift1<Tout, Tin1, Tout (*)(const Tin1&)>
00344 liftP( Tout (*fn)(const Tin1&) ) {
00345 return PipeModuleLift1<Tout,Tin1,Tout (*)(const Tin1&)>(fn);
00346 }
00347
00348
00349 template <class Tout, class Tin1, class Tin2, class Fn>
00350 class PipeModuleLift2 : public PipeLift2<Tout,Tin1,Tin2> {
00351 typedef PipeModuleLift2<Tout,Tin1,Tin2,Fn> ThisType ;
00352 typedef PipeLift2<Tout,Tin1,Tin2> BaseType ;
00353 protected:
00354 Fn fn ;
00355 Pipe<Tin1> *pred1 ;
00356 Pipe<Tin2> *pred2 ;
00357
00358 protected:
00359
00360 void setDependency(void)
00361 {
00362 addDependency((DependencyUnit**)&pred1);
00363 addDependency((DependencyUnit**)&pred2);
00364 }
00365 ThisType * duplicate(void) const { return new ThisType(*this); }
00366
00367 inline void check(void)
00368 { PipeModule<Tout>::check( (bool)fn&&pred1&&pred2 ); }
00369
00370 public:
00371
00372 PipeModuleLift2( Fn fnin ) : fn(fnin), pred1(0), pred2(0)
00373 { setDependency(); }
00374 PipeModuleLift2( const ThisType& p ) : BaseType(p), fn(p.fn),
00375 pred1(p.pred1), pred2(p.pred2) { setDependency(); }
00376
00377 virtual Pipe<Tout> operator ()( const Pipe<Tin1>& x1, const Pipe<Tin2>& x2 ) const
00378 {
00379 ThisType *p = duplicate();
00380 p->pred1 = new Pipe<Tin1>(x1);
00381 p->pred2 = new Pipe<Tin2>(x2);
00382 return Pipe<Tout>(p) ;
00383 }
00384
00385 Tout compute_local_fn( int fc )
00386 {
00387 check();
00388 return fn(pred1->get_value(fc),pred2->get_value(fc));
00389 }
00390 };
00391
00392 template<class Tout, class Tin1, class Tin2>
00393 class PipeModuleLift2Types {
00394 public:
00395 typedef PipeModuleLift2<Tout,Tin1,Tin2,Tout (*)(Tin1,Tin2)> Val;
00396 typedef PipeModuleLift2<Tout,Tin1,Tin2,
00397 Tout (*)(const Tin1&,const Tin2&)> Ref;
00398 };
00399
00400 template<class Tout, class Tin1, class Tin2>
00401 inline PipeModuleLift2<Tout, Tin1, Tin2, Tout (*)(Tin1,Tin2)>
00402 liftP( Tout (*fn)(Tin1,Tin2) ) {
00403 return PipeModuleLift2<Tout,Tin1,Tin2,Tout (*)(Tin1,Tin2)>(fn);
00404 }
00405 template<class Tout, class Tin1, class Tin2>
00406 inline PipeModuleLift2<Tout, Tin1, Tin2, Tout (*)(const Tin1&,Tin2)>
00407 liftP( Tout (*fn)(const Tin1&,Tin2) ) {
00408 return PipeModuleLift2<Tout,Tin1,Tin2,Tout (*)(const Tin1&,Tin2)>(fn);
00409 }
00410 template<class Tout, class Tin1, class Tin2>
00411 inline PipeModuleLift2<Tout, Tin1, Tin2, Tout (*)(Tin1,const Tin2&)>
00412 liftP( Tout (*fn)(Tin1,const Tin2&) ) {
00413 return PipeModuleLift2<Tout,Tin1,Tin2,Tout (*)(Tin1,const Tin2&)>(fn);
00414 }
00415 template<class Tout, class Tin1, class Tin2>
00416 inline PipeModuleLift2<Tout, Tin1, Tin2, Tout (*)(const Tin1&,const Tin2&)>
00417 liftP( Tout (*fn)(const Tin1&,const Tin2&) ) {
00418 return PipeModuleLift2<Tout,Tin1,Tin2,Tout (*)(const Tin1&,const Tin2&)>(fn);
00419 }
00420
00421 template <class Tout, class Tin1, class Tin2, class Tin3, class Fn>
00422 class PipeModuleLift3 : public PipeLift3<Tout,Tin1,Tin2,Tin3> {
00423 typedef PipeModuleLift3<Tout,Tin1,Tin2,Tin3,Fn> ThisType ;
00424 typedef PipeLift3<Tout,Tin1,Tin2,Tin3> BaseType ;
00425 protected:
00426 Fn fn ;
00427 Pipe<Tin1> *pred1 ;
00428 Pipe<Tin2> *pred2 ;
00429 Pipe<Tin3> *pred3 ;
00430
00431 protected:
00432
00433 void setDependency(void)
00434 {
00435 addDependency((DependencyUnit**)&pred1);
00436 addDependency((DependencyUnit**)&pred2);
00437 addDependency((DependencyUnit**)&pred3);
00438 }
00439 ThisType * duplicate(void) const { return new ThisType(*this); }
00440
00441 inline void check(void)
00442 { PipeModule<Tout>::check( (bool)fn && pred1 && pred2 && pred3 ); }
00443
00444 public:
00445
00446 PipeModuleLift3( Fn fnin ) : fn(fnin), pred1(0), pred2(0), pred3(0)
00447 { setDependency(); }
00448 PipeModuleLift3( const ThisType& p ) : BaseType(p), fn(p.fn),
00449 pred1(p.pred1), pred2(p.pred2), pred3(p.pred3) { setDependency(); }
00450
00451 Pipe<Tout> operator ()( const Pipe<Tin1>& x1, const Pipe<Tin2>& x2,
00452 const Pipe<Tin3>& x3 ) const
00453 {
00454 ThisType *p = duplicate();
00455 p->pred1 = new Pipe<Tin1>(x1);
00456 p->pred2 = new Pipe<Tin2>(x2);
00457 p->pred3 = new Pipe<Tin3>(x3);
00458 return Pipe<Tout>(p) ;
00459 }
00460
00461 Tout compute_local_fn( int fc )
00462 {
00463 check();
00464 return fn(pred1->get_value(fc),pred2->get_value(fc),
00465 pred3->get_value(fc));
00466 }
00467 };
00468
00469 template<class Tout, class Tin1, class Tin2, class Tin3>
00470 class PipeModuleLift3Types {
00471 public:
00472 typedef PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00473 Tout (*)(Tin1,Tin2,Tin3)> Val;
00474 typedef PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00475 Tout (*)(const Tin1&,const Tin2&,const Tin3&)> Ref;
00476 };
00477
00478 template<class Tout, class Tin1, class Tin2, class Tin3>
00479 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00480 Tout (*)(Tin1,Tin2,Tin3)>
00481 liftP( Tout (*fn)(Tin1,Tin2,Tin3) ) {
00482 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00483 Tout (*)(Tin1,Tin2,Tin3)>(fn);
00484 }
00485 template<class Tout, class Tin1, class Tin2, class Tin3>
00486 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00487 Tout (*)(Tin1,Tin2,const Tin3&)>
00488 liftP( Tout (*fn)(Tin1,Tin2,const Tin3&) ) {
00489 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00490 Tout (*)(Tin1,Tin2,const Tin3&)>(fn);
00491 }
00492 template<class Tout, class Tin1, class Tin2, class Tin3>
00493 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00494 Tout (*)(Tin1,const Tin2&,Tin3)>
00495 liftP( Tout (*fn)(Tin1,const Tin2&,Tin3) ) {
00496 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00497 Tout (*)(Tin1,const Tin2&,Tin3)>(fn);
00498 }
00499 template<class Tout, class Tin1, class Tin2, class Tin3>
00500 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00501 Tout (*)(Tin1,const Tin2&,const Tin3&)>
00502 liftP( Tout (*fn)(Tin1,const Tin2&,const Tin3&) ) {
00503 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00504 Tout (*)(Tin1,const Tin2&,const Tin3&)>(fn);
00505 }
00506 template<class Tout, class Tin1, class Tin2, class Tin3>
00507 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00508 Tout (*)(const Tin1&,Tin2,Tin3)>
00509 liftP( Tout (*fn)(const Tin1&,Tin2,Tin3) ) {
00510 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00511 Tout (*)(const Tin1&,Tin2,Tin3)>(fn);
00512 }
00513 template<class Tout, class Tin1, class Tin2, class Tin3>
00514 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00515 Tout (*)(const Tin1&,Tin2,const Tin3&)>
00516 liftP( Tout (*fn)(const Tin1&,Tin2,const Tin3&) ) {
00517 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00518 Tout (*)(const Tin1&,Tin2,const Tin3&)>(fn);
00519 }
00520 template<class Tout, class Tin1, class Tin2, class Tin3>
00521 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00522 Tout (*)(const Tin1&,const Tin2&,Tin3)>
00523 liftP( Tout (*fn)(const Tin1&,const Tin2&,Tin3) ) {
00524 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00525 Tout (*)(const Tin1&,const Tin2&,Tin3)>(fn);
00526 }
00527 template<class Tout, class Tin1, class Tin2, class Tin3>
00528 inline PipeModuleLift3<Tout, Tin1, Tin2, Tin3,
00529 Tout (*)(const Tin1&,const Tin2&,const Tin3&)>
00530 liftP( Tout (*fn)(const Tin1&,const Tin2&,const Tin3&) ) {
00531 return PipeModuleLift3<Tout,Tin1,Tin2,Tin3,
00532 Tout (*)(const Tin1&,const Tin2&,const Tin3&)>(fn);
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 template<class Tout, class Tvoid=Tout>
00546 class PipeModuleLiftImplicit0 : public PipeLift0<Tout> {
00547 typedef PipeModuleLiftImplicit0<Tout,Tvoid> ThisType ;
00548 typedef PipeLift0<Tout> BaseType ;
00549 protected:
00550 typedef Tvoid (*LiftImp0Type)( Tout& y );
00551 LiftImp0Type fn ;
00552
00553 protected:
00554
00555 void setDependency(void) {}
00556 ThisType * duplicate(void) const { return new ThisType(*this); }
00557
00558 protected:
00559
00560 inline void check(void) { PipeModule<Tout>::check( fn ); }
00561
00562 public:
00563
00564 PipeModuleLiftImplicit0( LiftImp0Type fnin ) : fn(fnin)
00565 { setDependency(); }
00566 PipeModuleLiftImplicit0( const ThisType& p) :
00567 BaseType(p), fn(p.fn) { setDependency(); }
00568 operator Pipe<Tout> () const { return Pipe<Tout>(duplicate()); }
00569
00570 Pipe<Tout> operator ()(void) const { return Pipe<Tout>(duplicate()); }
00571
00572 Tout compute_local_fn( int fc ) { check(); fn(value); return value ; }
00573 };
00574
00575 template<class Tout, class Tvoid>
00576 inline Pipe<Tout> liftP( Tvoid (*fn)(Tout&) ) {
00577 return Pipe<Tout>(new PipeModuleLiftImplicit0<Tout,Tvoid>(fn)) ;
00578 }
00579
00580 template<class Tout, class Tin1, class Tvoid=Tout>
00581 class PipeModuleLiftImplicit1 : public PipeLift1<Tout,Tin1> {
00582 typedef PipeModuleLiftImplicit1<Tout,Tin1,Tvoid> ThisType ;
00583 protected:
00584 typedef Tvoid (*LiftImp1Type1)( const Tin1& x1, Tout& y );
00585 typedef Tvoid (*LiftImp1Type2)( Tout& y, const Tin1& x1 );
00586 LiftImp1Type1 fn1 ;
00587 LiftImp1Type2 fn2 ;
00588 int which_fn ;
00589 Pipe<Tin1> *pred1 ;
00590
00591 protected:
00592
00593 void setDependency(void) { addDependency((DependencyUnit**)&pred1); }
00594 ThisType * duplicate(void) const { return new ThisType(*this); }
00595
00596 inline void check(void)
00597 { PipeModule<Tout>::check( (which_fn==1?fn1!=0:fn2!=0) && pred1 ); }
00598
00599 public:
00600
00601 PipeModuleLiftImplicit1( LiftImp1Type1 fnin ) :
00602 fn1(fnin), fn2(0), which_fn(1), pred1(0) { setDependency(); }
00603 PipeModuleLiftImplicit1( LiftImp1Type2 fnin ) :
00604 fn1(0), fn2(fnin), which_fn(2), pred1(0) { setDependency(); }
00605 PipeModuleLiftImplicit1( const PipeModuleLiftImplicit1<Tout,Tin1,Tvoid>& p ):
00606 PipeLift1<Tout,Tin1>(p), fn1(p.fn1), fn2(p.fn2),
00607 which_fn(p.which_fn), pred1(p.pred1) { setDependency(); }
00608
00609 Pipe<Tout> operator () ( const Pipe<Tin1>& x1 ) const
00610 {
00611 PipeModuleLiftImplicit1<Tout,Tin1,Tvoid> *p =
00612 new PipeModuleLiftImplicit1<Tout,Tin1,Tvoid>(*this) ;
00613 p->pred1 = new Pipe<Tin1>(x1);
00614 return Pipe<Tout>(p);
00615 }
00616
00617 Tout compute_local_fn( int fc )
00618 {
00619 check();
00620 if( which_fn == 1 ) {
00621 (*fn1)( pred1->get_value(fc), value );
00622 }else {
00623 (*fn2)( value, pred1->get_value(fc) );
00624 }
00625 return value ;
00626 }
00627 };
00628
00629 template<class Tout, class Tin1, class Tvoid>
00630 inline PipeModuleLiftImplicit1<Tout, Tin1, Tvoid>
00631 liftP( Tvoid (*fn)(const Tin1&, Tout&) ) {
00632 return PipeModuleLiftImplicit1<Tout,Tin1,Tvoid>(fn) ;
00633 }
00634
00635 template<class Tout, class Tin1, class Tvoid>
00636 inline PipeModuleLiftImplicit1<Tout, Tin1, Tvoid>
00637 liftP( Tvoid (*fn)(Tout&, const Tin1&) ) {
00638 return PipeModuleLiftImplicit1<Tout,Tin1,Tvoid>(fn) ;
00639 }
00640
00641
00642
00643 template<class Tout, class Tclass, class Fn>
00644 class PipeModuleLiftClass0 : public PipeLift0<Tout> {
00645 typedef PipeModuleLiftClass0<Tout,Tclass,Fn> ThisType ;
00646 protected:
00647 Fn fn ;
00648 Pipe<Tclass> * predc ;
00649
00650 protected:
00651 void setDependency(void) { addDependency((DependencyUnit**)&predc); }
00652 ThisType * duplicate(void) const { return new ThisType(*this); }
00653
00654 inline void check(void)
00655 { PipeModule<Tout>::check( (bool)fn && predc ); }
00656
00657 public:
00658
00659 PipeModuleLiftClass0( Fn fnin ) : fn(fnin), predc(0) { setDependency(); }
00660 PipeModuleLiftClass0( const Pipe<Tclass>& p, Fn fnin ) :
00661 fn(fnin), predc(new Pipe<Tclass>(p)) { setDependency(); }
00662 PipeModuleLiftClass0( const ThisType& p ) : PipeLift0<Tout>(p),
00663 fn(p.fn), predc(p.predc) { setDependency(); }
00664
00665 Pipe<Tout> operator ()(void) const
00666 {
00667 ThisType *p = new ThisType(*this);
00668 return Pipe<Tout>(p);
00669 }
00670
00671 Pipe<Tout> operator ()( const Pipe<Tclass>& x ) const
00672 {
00673 if( predc ) throw RedefPipe() ;
00674 ThisType *p = new ThisType(*this);
00675 p->predc = new Pipe<Tclass>(x);
00676 return Pipe<Tout>(p);
00677 }
00678
00679 Tout compute_local_fn( int fc )
00680 { check(); return (predc->get_value(fc).*fn)(); }
00681 };
00682
00683 template<class Tout, class Tclass>
00684 inline PipeModuleLiftClass0<Tout, Tclass, Tout (Tclass::*)(void)>
00685 liftP( const Pipe<Tclass>& p, Tout (Tclass::*fn)(void) ) {
00686 return PipeModuleLiftClass0<Tout, Tclass, Tout (Tclass::*)(void)>( p, fn );
00687 }
00688 template<class Tout, class Tclass>
00689 inline PipeModuleLiftClass0<Tout, Tclass, Tout (Tclass::*)(void)>
00690 liftP( Tout (Tclass::*fn)(void) ) {
00691 return PipeModuleLiftClass0<Tout, Tclass, Tout (Tclass::*)(void)>( fn );
00692 }
00693 template<class Tout, class Tclass>
00694 inline PipeModuleLiftClass0<Tout, Tclass, Tout (Tclass::*)(void) const>
00695 liftP( const Pipe<Tclass>& p, Tout (Tclass::*fn)(void) const ) {
00696 return PipeModuleLiftClass0<Tout, Tclass,
00697 Tout (Tclass::*)(void) const>( p, fn );
00698 }
00699 template<class Tout, class Tclass>
00700 inline PipeModuleLiftClass0<Tout, Tclass, Tout (Tclass::*)(void) const>
00701 liftP( Tout (Tclass::*fn)(void) const ) {
00702 return PipeModuleLiftClass0<Tout, Tclass,
00703 Tout (Tclass::*)(void) const>( fn );
00704 }
00705
00706 template<class Tout, class Tclass, class Tin1, class Fn>
00707 class PipeModuleLiftClass1 : public PipeModule<Tout> {
00708 typedef PipeModuleLiftClass1<Tout,Tclass,Tin1,Fn> ThisType ;
00709 protected:
00710 Fn fn ;
00711 Pipe<Tclass> * predc ;
00712 Pipe<Tin1> * pred1 ;
00713
00714 protected:
00715 void setDependency(void)
00716 {
00717 addDependency((DependencyUnit**)&predc);
00718 addDependency((DependencyUnit**)&pred1);
00719 }
00720 ThisType * duplicate(void) const { return new ThisType(*this); }
00721
00722 inline void check(void)
00723 { PipeModule<Tout>::check( (bool)fn && predc && pred1 ); }
00724
00725 public:
00726
00727 PipeModuleLiftClass1( Fn fnin ) :
00728 fn(fnin), predc(0), pred1(0) { setDependency(); }
00729 PipeModuleLiftClass1( const ThisType& p ) : PipeModule<Tout>(p),
00730 fn(p.fn), predc(p.predc), pred1(p.pred1) { setDependency(); }
00731
00732 Pipe<Tout> operator ()( const Pipe<Tclass>& t, const Pipe<Tin1>& x1 ) const
00733 {
00734 ThisType *p = new ThisType(*this);
00735 p->predc = new Pipe<Tclass>(t);
00736 p->pred1 = new Pipe<Tin1>(x1);
00737 return Pipe<Tout>(p);
00738 }
00739
00740 Tout compute_local_fn( int fc )
00741 { check(); return (predc->get_value(fc).*fn)(pred1->get_value(fc)); }
00742 };
00743
00744 template<class Tout, class Tclass, class Tin1>
00745 inline PipeModuleLiftClass1<Tout, Tclass, Tin1, Tout (Tclass::*)(Tin1)>
00746 liftP( Tout (Tclass::*fn)(Tin1) ) {
00747 return PipeModuleLiftClass1<Tout, Tclass, Tin1,
00748 Tout (Tclass::*)(Tin1)>( fn );
00749 }
00750 template<class Tout, class Tclass, class Tin1>
00751 inline PipeModuleLiftClass1<Tout, Tclass, Tin1, Tout (Tclass::*)(const Tin1&)>
00752 liftP( Tout (Tclass::*fn)(const Tin1&) ) {
00753 return PipeModuleLiftClass1<Tout, Tclass, Tin1,
00754 Tout (Tclass::*)(const Tin1&)>( fn );
00755 }
00756
00757
00758
00759 template<class Tout, class Tclass, class Fn>
00760 class PipeModuleClassLift0 : public PipeModule<Tout> {
00761 typedef PipeModuleClassLift0<Tout,Tclass,Fn> ThisType;
00762 protected:
00763 Tclass host ;
00764 Fn fn ;
00765
00766 protected:
00767
00768 void setDependency(void) {}
00769 ThisType * duplicate(void) const { return new ThisType(*this);}
00770
00771 protected:
00772
00773 inline void check(void) { PipeModule<Tout>::check( fn ); }
00774
00775 public:
00776
00777 PipeModuleClassLift0( const Tclass& obj, Fn fnin ) : host(obj), fn(fnin)
00778 { setDependency(); }
00779 PipeModuleClassLift0( const ThisType& p ) : PipeModule<Tout>(p),
00780 host(p.host), fn(p.fn) { setDependency(); }
00781
00782 operator Pipe<Tout> () const
00783 { return Pipe<Tout>(new ThisType(*this)); }
00784
00785 Pipe<Tout> operator ()(void) const
00786 { ThisType *p = new ThisType(*this) ; return Pipe<Tout>(p) ; }
00787
00788 Tout compute_local_fn( int fc ) { check(); return (host.*fn)(); }
00789 };
00790
00791 template<class Tout, class Tclass>
00792 inline Pipe<Tout> liftP( const Tclass& obj, Tout (Tclass::*fn)(void) ) {
00793 return Pipe<Tout>(new PipeModuleClassLift0
00794 <Tout,Tclass,Tout (Tclass::*)(void)>(obj,fn));
00795 }
00796 template<class Tout, class Tclass>
00797 inline Pipe<Tout> liftP( const Tclass& obj, Tout (Tclass::*fn)(void) const ) {
00798 return Pipe<Tout>(new PipeModuleClassLift0
00799 <Tout,Tclass,Tout (Tclass::*)(void) const>(obj,fn));
00800 }
00801
00802 template<class Tout, class Tin1, class Tclass, class Fn>
00803 class PipeModuleClassLift1 : public PipeLift1<Tout,Tin1> {
00804 typedef PipeModuleClassLift1<Tout,Tin1,Tclass,Fn> ThisType;
00805 protected:
00806 Tclass host ;
00807 Fn fn ;
00808 Pipe<Tin1> * pred1 ;
00809
00810 protected:
00811
00812 void setDependency(void) { addDependency((DependencyUnit**)&pred1); }
00813 ThisType * duplicate(void) const { return new ThisType(*this);}
00814
00815 inline void check(void) { PipeModule<Tout>::check( (bool)fn && pred1 ); }
00816
00817 public:
00818
00819 PipeModuleClassLift1( const Tclass& obj, Fn fnin ) :
00820 host(obj), fn(fnin), pred1(0) { setDependency(); }
00821 PipeModuleClassLift1( const ThisType& p ) : PipeLift1<Tout,Tin1>(p),
00822 host(p.host), fn(p.fn), pred1(p.pred1) { setDependency(); }
00823
00824 Pipe<Tout> operator ()( const Pipe<Tin1>& x1 ) const
00825 {
00826 ThisType *p = new ThisType(*this) ;
00827 p->pred1 = new Pipe<Tin1>(x1) ;
00828 return Pipe<Tout>(p) ;
00829 }
00830
00831 Tout compute_local_fn( int fc )
00832 { check(); return (host.*fn)(pred1->get_value(fc)); }
00833 };
00834
00835 template<class Tout, class Tin, class Tclass>
00836 inline PipeModuleClassLift1<Tout,Tin,Tclass,Tout (Tclass::*)(Tin)>
00837 liftP( const Tclass& obj, Tout (Tclass::*fn)(Tin) ) {
00838 return PipeModuleClassLift1 <Tout,Tin,Tclass,Tout (Tclass::*)(Tin)>(obj,fn);
00839 }
00840 template<class Tout, class Tin, class Tclass>
00841 inline PipeModuleClassLift1<Tout,Tin,Tclass,Tout (Tclass::*)(Tin) const>
00842 liftP( const Tclass& obj, Tout (Tclass::*fn)(Tin) const ) {
00843 return PipeModuleClassLift1
00844 <Tout,Tin,Tclass,Tout (Tclass::*)(Tin) const>(obj,fn);
00845 }
00846 template<class Tout, class Tin, class Tclass>
00847 inline PipeModuleClassLift1<Tout,Tin,Tclass,Tout (Tclass::*)(const Tin&)>
00848 liftP( const Tclass& obj, Tout (Tclass::*fn)(const Tin&) ) {
00849 return PipeModuleClassLift1
00850 <Tout,Tin,Tclass,Tout (Tclass::*)(const Tin&)>(obj,fn);
00851 }
00852 template<class Tout, class Tin, class Tclass>
00853 inline PipeModuleClassLift1
00854 <Tout,Tin,Tclass,Tout (Tclass::*)(const Tin&) const>
00855 liftP( const Tclass& obj, Tout (Tclass::*fn)(const Tin&) const ) {
00856 return PipeModuleClassLift1
00857 <Tout,Tin,Tclass,Tout (Tclass::*)(const Tin&) const>(obj,fn);
00858 }
00859
00860
00861
00862
00863
00864
00865 template<class Tout, class Tclass>
00866 inline PipeModuleLift1<Tout,Tclass,XVDataMemFun<Tout Tclass::*,Tout,Tclass> >
00867 liftP( Tout Tclass::*f ) {
00868 return PipeModuleLift1<Tout,Tclass,XVDataMemFun<Tout Tclass::*,Tout,Tclass> >
00869 (XVDataMemFun<Tout Tclass::*,Tout,Tclass>(f));
00870 }
00871
00872 template<class T1, class T2>
00873 inline T1 implicitCast( const T2& x ) {
00874 return x ;
00875 }
00876
00877 template <class T1, class T2>
00878 inline Pipe<T1> castP( const Pipe<T2>& x ) {
00879 PipeModuleLift1<T1,T2,T1 (*)(const T2&)> cast(implicitCast<T1,T2>);
00880 return cast(x) ;
00881 }
00882
00883
00884
00885 template<class T>
00886 class PipeDelay : public PipeModule<T> {
00887
00888
00889 T next ;
00890 Pipe<T> *pred ;
00891
00892 protected:
00893
00894 void setDependency(void) { addDependency((DependencyUnit**)&pred); }
00895 PipeDelay<T> * duplicate(void) const { return new PipeDelay<T>(*this); }
00896
00897 inline void check(void) { PipeModule<T>::check( pred ); }
00898
00899 public:
00900
00901 PipeDelay( const T& x ) : next(x), pred(0) { setDependency(); }
00902 PipeDelay( const PipeDelay<T>& p ) : PipeModule<T>(p),
00903 next(p.next), pred(p.pred) { setDependency(); }
00904
00905 Pipe<T> operator () ( const Pipe<T>& x ) const
00906 {
00907 PipeDelay<T> *p = new PipeDelay<T>(*this);
00908 p->pred = new Pipe<T>(x) ;
00909 return Pipe<T>(p);
00910 }
00911
00912 void get_value( int fc, T * addr ) { *addr = get_value( fc ); }
00913
00914 T get_value( int fc )
00915 {
00916 if( fc != frame_count ) {
00917 check();
00918 value = next ;
00919 frame_count = fc ;
00920 update( frame_count, value );
00921 pred->get_value( fc, &next );
00922 }
00923 return value ;
00924 }
00925 };
00926
00927 template<class T>
00928 inline PipeDelay<T> delayP( const T& x ) {
00929 return PipeDelay<T>(x) ;
00930 }
00931
00932
00933
00934 template<class T1, class T2>
00935 inline typename T1::ResultType
00936 operator <<= ( const T1& x1, const T2& x2 ) {
00937 return x1(x2);
00938 }
00939
00940
00941
00942 template<class T1, class T2>
00943 inline T2 useSecondPipe( const T1&, const T2& x2 ) { return x2 ; }
00944
00945 template<class T1, class T2>
00946 inline Pipe<T2> operator >>= ( const Pipe<T1>& p1, const Pipe<T2>& p2 ) {
00947 PipeModuleLift2<T2,T1,T2,T2 (*)(const T1&,const T2&)> p(useSecondPipe<T1,T2>);
00948 return p( p1, p2 ) ;
00949 }
00950
00951 # define PARALLEL_P >>=
00952
00953
00954
00955
00956
00957 #define LiftBinOp(OP,NM) \
00958 template<class Tout, class Tin1, class Tin2>\
00959 class PipeModuleLiftBin##NM: public PipeModule<Tout> {\
00960 typedef PipeModuleLiftBin##NM<Tout,Tin1,Tin2> ThisType ; \
00961 protected:\
00962 Pipe<Tin1> *pred1; \
00963 Pipe<Tin2> *pred2; \
00964 \
00965 protected:\
00966 void setDependency(void) \
00967 { \
00968 addDependency((DependencyUnit**)&pred1); \
00969 addDependency((DependencyUnit**)&pred2); \
00970 } \
00971 ThisType * duplicate(void) const { return new ThisType(*this); } \
00972 \
00973 inline void check(void) { PipeModule<Tout>::check( pred1 && pred2 ); }\
00974 \
00975 public:\
00976 \
00977 PipeModuleLiftBin##NM(const Pipe<Tin1>& x, const Pipe<Tin2>& y) : \
00978 PipeModule<Tout>(), pred1(new Pipe<Tin1>(x)), pred2(new Pipe<Tin2>(y)) \
00979 { setDependency(); } \
00980 PipeModuleLiftBin##NM( const ThisType& p) : \
00981 PipeModule<Tout>(p), pred1(p.pred1), pred2(p.pred2) \
00982 { setDependency(); } \
00983 \
00984 Tout compute_local_fn(int fc) \
00985 { check(); return pred1->get_value(fc) OP pred2->get_value(fc) ; } \
00986 };\
00987 \
00988 template <class T1, class T2>\
00989 Pipe<T1> operator OP(const Pipe<T1>& x, const Pipe<T2>& y)\
00990 {\
00991 return Pipe<T1>(new PipeModuleLiftBin##NM<T1,T1,T2>(x,y));\
00992 }\
00993 template <class T1, class T2>\
00994 Pipe<T1> operator OP( const Pipe<T1>& x, const T2 y)\
00995 {\
00996 return Pipe<T1>(new PipeModuleLiftBin##NM<T1,T1,T2>(x,y));\
00997 }\
00998 template <class T1, class T2>\
00999 Pipe<T1> &operator OP(const T1 x, const Pipe<T2>& y)\
01000 {\
01001 return Pipe<T1>(new PipeModuleLiftBin##NM<T1,T1,T2>(x,y));\
01002 }\
01003
01004 LiftBinOp(+,Plus);
01005 LiftBinOp(-,Minus);
01006 LiftBinOp(*,Multiply);
01007 LiftBinOp(/,Divide);
01008 LiftBinOp(<<,LeftShift);
01009 LiftBinOp(>>,RightShift);
01010
01011
01012 LiftBinOp(&,BitwiseAnd);
01013 LiftBinOp(|,BitWiseOr);
01014
01015
01016
01017
01018
01019 #define LiftUnOp(OP,NM) \
01020 template<class T>\
01021 class PipeModuleLiftUn##NM: public PipeModule<T> {\
01022 typedef PipeModuleLiftUn##NM<T> ThisType ; \
01023 protected:\
01024 Pipe<T> *pred; \
01025 \
01026 protected:\
01027 void setDependency(void) { addDependency((DependencyUnit**)&pred); } \
01028 \
01029 ThisType * duplicate(void) const { return new ThisType(*this); } \
01030 \
01031 inline void check(void) { PipeModule<T>::check( pred ); }\
01032 \
01033 public:\
01034 \
01035 PipeModuleLiftUn##NM( const Pipe<T>& x ) : \
01036 PipeModule<T>(), pred(new Pipe<T>(x)) { setDependency(); } \
01037 PipeModuleLiftUn##NM( const ThisType& p ) : \
01038 PipeModule<T>(p), pred(p.pred) { setDependency(); } \
01039 \
01040 T compute_local_fn(int fc) { check(); return OP pred->get_value(fc); } \
01041 };\
01042 \
01043 template<class T> \
01044 inline Pipe<T> operator OP ( const Pipe<T>& x ) { \
01045 return Pipe<T>(new PipeModuleLiftUn##NM<T>(x)) ; \
01046 } \
01047
01048 LiftUnOp(!,Not)
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 template<class Tout>
01060 class PipeFun0 : public PipeLift0<Tout> {
01061 typedef PipeFun0<Tout> ThisType ;
01062 typedef PipeLift0<Tout> BaseType ;
01063 protected:
01064 Pipe<Tout> * result ;
01065
01066 protected:
01067 void setDependency(void)
01068 { addDependency((DependencyUnit**)&result); }
01069 ThisType * duplicate(void) const { return new ThisType(*this); }
01070
01071 inline void check(void) { return PipeModule<Tout>::check(result);}
01072
01073 public:
01074 PipeFun0() : result(0) { setDependency(); }
01075 PipeFun0( const ThisType& p ) : BaseType(p),
01076 result(p.result) { setDependency(); }
01077
01078 Pipe<Tout> operator() (void)
01079 {
01080 check();
01081 ThisType *p = (ThisType *) copy();
01082 return Pipe<Tout>(p) ;
01083 }
01084
01085
01086 Pipe<Tout> operator() (void) const
01087 { return (*const_cast<ThisType*>(this))() ; }
01088
01089 ThisType& operator = ( const Pipe<Tout>& p )
01090 {
01091 if( result ) throw RedefPipe() ;
01092 result = new Pipe<Tout>(p) ;
01093 return *this;
01094 }
01095
01096 ThisType& operator = ( const ThisType& p )
01097 {
01098 if( &p != this ) {
01099 if( result ) throw RedefPipe() ;
01100 result = p.result ;
01101 return *this;
01102 }
01103 }
01104
01105 Tout get_value( int fc ) { check(); return result->get_value(fc); }
01106 };
01107
01108 template<class Tout>
01109 PipeFun0<Tout>
01110 lambdaP( const Pipe<Tout>& f ) {
01111 PipeFun0<Tout> p;
01112 return p = f ;
01113 }
01114
01115 template<class Tout, class Tin1>
01116 class PipeFun1 : public PipeLift1<Tout,Tin1> {
01117 typedef PipeFun1<Tout,Tin1> ThisType ;
01118 typedef PipeLift1<Tout,Tin1> BaseType ;
01119 protected:
01120 Pipe<Tout> * result ;
01121 Pipe<Tin1> * param1 ;
01122
01123 protected:
01124
01125 void setDependency(void)
01126 {
01127 addDependency((DependencyUnit**)&result);
01128 addDependency((DependencyUnit**)¶m1);
01129 }
01130 ThisType * duplicate(void) const { return new ThisType(*this); }
01131
01132 inline void check(void) { return PipeModule<Tout>::check(result&¶m1);}
01133
01134 public:
01135 PipeFun1() : result(0), param1(0) { setDependency(); }
01136 PipeFun1( Pipe<Tin1>& p1 ) : result(0), param1(&p1) {setDependency();}
01137 PipeFun1( const ThisType& p ) : BaseType(p),
01138 result(p.result), param1(p.param1) { setDependency(); }
01139
01140 ThisType& operator () ( Pipe<Tin1>& p1, void * dummy )
01141 {
01142 if( param1 ) throw RedefPipe() ;
01143 param1 = &p1 ;
01144 return *this ;
01145 }
01146
01147 Pipe<Tout> operator() ( const Pipe<Tin1>& x1 )
01148 {
01149 check();
01150 PipeModule<Tin1> dummy1, * save1 = *(param1->module) ;
01151 *(param1->module) = &dummy1 ;
01152 ThisType *p = (ThisType *) copy();
01153 delete *(p->param1->module) ;
01154 *(p->param1->module) = new Pipe<Tin1>(x1) ;
01155 *(param1->module) = save1 ;
01156 return Pipe<Tout>(p) ;
01157 }
01158
01159
01160 Pipe<Tout> operator() ( const Pipe<Tin1>& x1 ) const
01161 { return (*const_cast<ThisType*>(this))(x1) ; }
01162
01163 ThisType& operator = ( const Pipe<Tout>& p )
01164 {
01165 if( result ) throw RedefPipe() ;
01166 result = new Pipe<Tout>(p) ;
01167 return *this;
01168 }
01169
01170 ThisType& operator = ( const ThisType& p )
01171 {
01172 if( &p != this ) {
01173 if( result || param1 ) throw RedefPipe() ;
01174 result = p.result ;
01175 param1 = p.param1 ;
01176 return *this;
01177 }
01178 }
01179
01180 Tout get_value( int fc ) { check(); return result->get_value(fc); }
01181 };
01182
01183 template<class Tout, class Tin1>
01184 PipeFun1<Tout,Tin1>
01185 lambdaP( Pipe<Tin1>& x1, const Pipe<Tout>& f ) {
01186 PipeFun1<Tout,Tin1> p(x1);
01187 return p = f ;
01188 }
01189
01190 template<class Tout, class Tin1, class Tin2>
01191 class PipeFun2 : public PipeLift2<Tout,Tin1,Tin2> {
01192 typedef PipeFun2<Tout,Tin1,Tin2> ThisType ;
01193 typedef PipeLift2<Tout,Tin1,Tin2> BaseType ;
01194 protected:
01195 Pipe<Tout> * result ;
01196 Pipe<Tin1> * param1 ;
01197 Pipe<Tin2> * param2 ;
01198
01199 protected:
01200
01201 void setDependency(void)
01202 {
01203 addDependency((DependencyUnit**)&result);
01204 addDependency((DependencyUnit**)¶m1);
01205 addDependency((DependencyUnit**)¶m2);
01206 }
01207 ThisType * duplicate(void) const { return new ThisType(*this); }
01208
01209 inline void check(void)
01210 { return PipeModule<Tout>::check(result&¶m1&¶m2);}
01211
01212 public:
01213 PipeFun2() : result(0), param1(0), param2(0) { setDependency(); }
01214 PipeFun2( Pipe<Tin1>& p1, Pipe<Tin2>&p2 ) : result(0),
01215 param1(&p1), param2(&p2) {setDependency();}
01216 PipeFun2( const ThisType& p ) : BaseType(p), result(p.result),
01217 param1(p.param1), param2(p.param2) { setDependency(); }
01218
01219 ThisType& operator () ( Pipe<Tin1>& p1, Pipe<Tin2>& p2, void * dummy )
01220 {
01221 if( param1 || param2 ) throw RedefPipe() ;
01222 param1 = &p1 ;
01223 param2 = &p2 ;
01224 return *this ;
01225 }
01226
01227 Pipe<Tout> operator() ( const Pipe<Tin1>& x1, const Pipe<Tin2>& x2 )
01228 {
01229 check();
01230 PipeModule<Tin1> dummy1, * save1 = *(param1->module) ;
01231 *(param1->module) = &dummy1 ;
01232 PipeModule<Tin2> dummy2, * save2 = *(param2->module) ;
01233 *(param2->module) = &dummy2 ;
01234 ThisType *p = (ThisType *) copy();
01235 delete *(p->param1->module) ;
01236 *(p->param1->module) = new Pipe<Tin1>(x1) ;
01237 *(param1->module) = save1 ;
01238 delete *(p->param2->module) ;
01239 *(p->param2->module) = new Pipe<Tin2>(x2) ;
01240 *(param2->module) = save2 ;
01241 return Pipe<Tout>(p) ;
01242 }
01243
01244
01245 Pipe<Tout> operator() ( const Pipe<Tin1>& x1, const Pipe<Tin2>& x2 ) const
01246 { return (*const_cast<ThisType*>(this))(x1,x2) ; }
01247
01248 ThisType& operator = ( const Pipe<Tout>& p )
01249 {
01250 if( result ) throw RedefPipe() ;
01251 result = new Pipe<Tout>(p) ;
01252 return *this;
01253 }
01254
01255 ThisType& operator = ( const ThisType& p )
01256 {
01257 if( &p != this ) {
01258 if( result || param1 || param2 ) throw RedefPipe() ;
01259 result = p.result ;
01260 param1 = p.param1 ;
01261 param2 = p.param2 ;
01262 return *this;
01263 }
01264 }
01265
01266 Tout get_value( int fc ) { check(); return result->get_value(fc); }
01267 };
01268
01269 template<class Tout, class Tin1, class Tin2>
01270 PipeFun2<Tout,Tin1,Tin2>
01271 lambdaP( Pipe<Tin1>& x1, Pipe<Tin2>& x2, const Pipe<Tout>& f ) {
01272 PipeFun2<Tout,Tin1,Tin2> p(x1, x2);
01273 return p = f ;
01274 }
01275
01276
01277
01278
01279
01280
01281
01282 template<class T1, class T2>
01283 class Pair {
01284 public:
01285 T1 lval;
01286 T2 rval;
01287
01288 Pair() {};
01289 Pair( const T1& x, const T2& y ) : lval(x), rval(y) {};
01290
01291 T1 lVal(void) const { return lval ; }
01292 T2 rVal(void) const { return rval ; }
01293 };
01294
01295 template<class T1, class T2>
01296 Pair< T1,T2 > Pairup( T1 x, T2 y )
01297 {
01298 return Pair<T1,T2>(x,y);
01299 }
01300
01301 template <class T1, class T2>
01302 Pipe< Pair<T1,T2> > operator&&( const Pipe<T1>& x, const Pipe<T2>& y)
01303 {
01304 Pair<T1,T2> (*Pairupf)( T1, T2 ) = &Pairup;
01305 PipeModuleLift2<Pair<T1,T2>,T1,T2,Pair<T1,T2> (*)(T1,T2)> temp(Pairupf);
01306
01307 return temp(x,y);
01308 }
01309
01310 # endif //_PIPEMODULES_H_