00001 # ifndef _PIPEEVENTS_H_
00002 # define _PIPEEVENTS_H_
00003
00004 # include "PipeModules.h"
00005
00006
00007
00008
00009
00010
00011 template<class T>
00012 class Maybe : protected Pair<bool,T> {
00013 public:
00014 Maybe() : Pair<bool,T>() { lval = false ; }
00015 Maybe( const T& x ) : Pair<bool,T>(true,x) {}
00016 Maybe( bool f, const T& x ) : Pair<bool,T>(f,x) {}
00017 Maybe( const Maybe<T>& x ) : Pair<bool,T>(x) {}
00018 Maybe<T>& operator = (const Maybe<T>& x)
00019 {
00020 if( &x != this ) {
00021 if( lval = x.lval ) {
00022 rval = x.rval ;
00023 }
00024 }
00025 return *this ;
00026 }
00027
00028 bool hasValue(void) const { return lval ; }
00029 T getValue(void) const { return rval ; }
00030 operator bool () const { return hasValue(); }
00031 bool operator ! () const { return !hasValue(); }
00032 T operator *() const { return getValue(); }
00033 };
00034
00035 template<class T>
00036 inline Maybe<T> maybePair( bool f, const T& x ) {
00037 return Maybe<T>(f,x);
00038 }
00039
00040 template<class T>
00041 inline Pipe<Maybe<T> > maybeP( const Pipe<bool>& x1, const Pipe<T>& x2 ) {
00042 PipeModuleLift2<Maybe<T>,bool,T,Maybe<T> (*)(bool, const T&)> pair
00043 (maybePair<T>) ;
00044 return pair(x1,x2);
00045 }
00046
00047 template<class T1, class T2>
00048 Maybe<Pair<T1,T2> > maybeAnd ( const Maybe<T1>& x1,
00049 const Maybe<T2>& x2 ) {
00050 if( x1 && x2 ) {
00051 return Maybe<Pair<T1,T2> >(Pair<T1,T2>(*x1,*x2));
00052 }else {
00053 return Maybe<Pair<T1,T2> >();
00054 }
00055 }
00056
00057 template<class T1, class T2>
00058 Maybe<Pair<T1,T2> > maybeOr ( const Maybe<T1>& x1,
00059 const Maybe<T2>& x2 ) {
00060 if( x1 || x2 ) {
00061 return Maybe<Pair<T1,T2> >(Pair<T1,T2>(*x1,*x2));
00062 }else {
00063 return Maybe<Pair<T1,T2> >();
00064 }
00065 }
00066
00067
00068
00069 template<class T>
00070 class PipeEvents : public Pipe<Maybe<T> > {
00071 protected:
00072
00073 PipeEvents<T>* duplicate(void) const { return new PipeEvents<T>(*this); }
00074
00075 public:
00076
00077 PipeEvents() : Pipe<Maybe<T> >() {}
00078 PipeEvents( const PipeEvents<T>& p ) : Pipe<Maybe<T> >(p) {}
00079 PipeEvents( const Pipe<Maybe<T> >& p ) : Pipe<Maybe<T> >(p) {}
00080 PipeEvents( PipeModule<Maybe<T> > *v ) : Pipe<Maybe<T> >(v) {}
00081
00082 PipeEvents<T>& operator = ( const PipeEvents<T>& p )
00083 { Pipe<Maybe<T> >::operator = (p); return *this ; }
00084 PipeEvents<T>& operator = ( const Pipe<Maybe<T> >& p )
00085 { Pipe<Maybe<T> >::operator = (p); return *this ; }
00086
00087 bool hasValue(void) { return current_value().hasValue() ; }
00088 bool hasValue( int fc ) { return get_value(fc).hasValue() ; }
00089 T getValue( int fc ) { return get_value(fc).getValue() ; }
00090 };
00091
00092
00093 template<class T, class Fn>
00094 inline PipeEvents<T> whileP( Fn fn, const Pipe<T>& p ) {
00095 return PipeEvents<T>( maybeP<T>( liftP(fn)(p), p ) );
00096 }
00097
00098 inline PipeEvents<bool> whileP( const Pipe<bool>& p ) {
00099 return PipeEvents<bool>( maybeP<bool>( p, p ) );
00100 }
00101
00102
00103
00104 template<class T, class Fn>
00105 class PipeWhileModule : XVFunctoid1<Fn,PipeEvents<T>,Pipe<T> > {
00106 typedef XVFunctoid1<Fn,PipeEvents<T>,Pipe<T> > BaseType ;
00107 public:
00108 PipeWhileModule( Fn fn ) : BaseType(fn) {}
00109 virtual PipeEvents<T> operator () ( const Pipe<T>& x )
00110 { return maybeP<T>( liftP(f)(x), x ) ; }
00111 };
00112
00113 template<class T, class Fn>
00114 inline PipeWhileModule<T,Fn> whileP( Fn fn ) {
00115 return PipeWhileModule<T,Fn>(fn);
00116 }
00117 template<class T>
00118 inline PipeWhileModule<T,bool (*)(T)> whileP( bool (*fn)(T) ) {
00119 return PipeWhileModule<T,bool (*)(T)>(fn);
00120 }
00121 template<class T>
00122 inline PipeWhileModule<T,bool (*)(const T&)> whileP( bool (*fn)(const T&) ) {
00123 return PipeWhileModule<T,bool (*)(const T&)>(fn);
00124 }
00125
00126
00127
00128 template<class T>
00129 Maybe<T> maybeNotAnd ( const Maybe<T>& x1, const Maybe<T>& x2 ) {
00130 if( !x1 && x2 ) {
00131 return x2;
00132 }else {
00133 return Maybe<T>();
00134 }
00135 }
00136
00137 template<class T>
00138 inline PipeEvents<T> uniqueP( const PipeEvents<T>& p ) {
00139 typedef Maybe<T> MT ;
00140 PipeModuleLift2<MT,MT,MT,MT (*)(const MT&,const MT&)> ufun(maybeNotAnd<T>) ;
00141 return ufun( delayP(Maybe<T>()) <<= p, p ) ;
00142 }
00143
00144
00145
00146 template<class T, class Fn>
00147 class PipeWhenModule : XVFunctoid1<Fn,PipeEvents<T>,Pipe<T> > {
00148 typedef XVFunctoid1<Fn,PipeEvents<T>,Pipe<T> > BaseType ;
00149 public:
00150 PipeWhenModule( Fn fn ) : BaseType(fn) {}
00151 virtual PipeEvents<T> operator () ( const Pipe<T>& x )
00152 { return uniqueP( PipeEvents<T>( maybeP<T>( liftP(f)(x), x ) ) ); }
00153 };
00154
00155 template<class T, class Fn>
00156 inline PipeWhenModule<T,Fn> whenP( Fn fn ) {
00157 return PipeWhenModule<T,Fn>(fn);
00158 }
00159 template<class T>
00160 inline PipeWhenModule<T,bool (*)(T)> whenP( bool (*fn)(T) ) {
00161 return PipeWhenModule<T,bool (*)(T)>(fn);
00162 }
00163 template<class T>
00164 inline PipeWhenModule<T,bool (*)(const T&)> whenP( bool (*fn)(const T&) ) {
00165 return PipeWhenModule<T,bool (*)(const T&)>(fn);
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 template<class T1, class T2>
00178 PipeEvents<T2> thenPs( const PipeEvents<T1>& e, const Pipe<T2>& p ) {
00179 return maybeP( liftP(&Maybe<T1>::hasValue)(e), p );
00180 }
00181
00182 template<class T1, class T2>
00183 PipeEvents<Pipe<T2>*> thenPd( const PipeEvents<T1>& e, const Pipe<T2>& p ) {
00184 return maybeP( liftP(&Maybe<T1>::hasValue)(e),
00185 Pipe<Pipe<T2>*>(new Pipe<T2>(p)) );
00186 }
00187
00188 template<class T1, class T2>
00189 inline PipeEvents<T2> thenP( const PipeEvents<T1>& e, const Pipe<T2>& p ) {
00190 return thenPs(e,p) ;
00191 }
00192
00193 template<class T1, class T2>
00194 inline PipeEvents<T2>
00195 operator |= ( const PipeEvents<T1>& e, const Pipe<T2>& p ) {
00196 return thenP( e, p );
00197 }
00198
00199
00200
00201 template<class T>
00202 T switchFunS( const Maybe<T>& x1, const T& x2 ) {
00203 if( x1 ) {
00204 return x1.getValue() ;
00205 }else {
00206 return x2 ;
00207 }
00208 }
00209
00210
00211 template<class T>
00212 inline Pipe<T> switchPs( const Pipe<T>& p, const PipeEvents<T>& e ) {
00213 PipeModuleLift2<T,Maybe<T>,T,T (*)(const Maybe<T>&, const T&)> sfun
00214 (switchFunS<T>) ;
00215 return sfun( e, p );
00216 }
00217
00218 template<class T>
00219 class SwitchFunD : public XVFunctoid2<int,T,T,Maybe<Pipe<T>*> >{
00220 typedef XVFunctoid2<int,T,T,Maybe<Pipe<T>*> > BaseType ;
00221 public:
00222 SwitchFunD( int fc ) : BaseType(fc) {}
00223 int set( int fc ) { return f = fc ; }
00224 operator bool (void) { return true ; }
00225 T operator ()( const T& x, const Maybe<Pipe<T>*>& e )
00226 { if( e ) return e.getValue()->get_value(f) ; else return x ; }
00227 };
00228
00229
00230 template<class T>
00231 class PipeModuleSwitchD :
00232 public PipeModuleLift2<T,T,Maybe<Pipe<T>*>,SwitchFunD<T> > {
00233 typedef PipeModuleSwitchD<T> ThisType ;
00234 typedef PipeModuleLift2<T,T,Maybe<Pipe<T>*>,SwitchFunD<T> > BaseType ;
00235 protected:
00236 ThisType * duplicate(void) const { return new ThisType(*this); }
00237 public:
00238 PipeModuleSwitchD() : BaseType(0) {}
00239 PipeModuleSwitchD( const ThisType& p ) : BaseType(p) {}
00240 T compute_local_fn( int fc )
00241 { return BaseType::compute_local_fn( fn.set(fc) ) ; }
00242 };
00243
00244 template<class T>
00245 inline Pipe<T> switchPd( const Pipe<T>& p, const PipeEvents<Pipe<T>*>& e ) {
00246 PipeModuleSwitchD<T> sfun ;
00247 return sfun(p,e);
00248 }
00249
00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294 00295 00296 00297 00298 00299 00300
00301
00302 template<class T>
00303 inline Pipe<T> switchP( const Pipe<T>& p, const PipeEvents<T>& e ) {
00304 return switchPs( p, e );
00305 }
00306
00307 template<class T>
00308 inline Pipe<T>
00309 operator *= ( const Pipe<T>& p, const PipeEvents<T>& e ) {
00310 return switchP( p, e );
00311 }
00312
00313 # define SWITCH_P *=
00314
00315
00316
00317 template<class T1, class T2>
00318 PipeEvents<Pair<T1,T2> > operator && ( const PipeEvents<T1>& x1,
00319 const PipeEvents<T2>& x2 ) {
00320 return PipeEvents<Pair<T1,T2> >( liftP(maybeAnd<T1,T2>)(x1,x2) );
00321 }
00322 template<class T1, class T2>
00323 PipeEvents<Pair<T1,T2> > operator || ( const PipeEvents<T1>& x1,
00324 const PipeEvents<T2>& x2 ) {
00325 return PipeEvents<Pair<T1,T2> >( liftP(maybeOr<T1,T2>)(x1,x2) );
00326 }
00327
00328 template<class T>
00329 class PipeEventOnce : public PipeModule<Maybe<T> > {
00330 typedef PipeEventOnce<T> ThisType ;
00331 typedef PipeModule<Maybe<T> > BaseType ;
00332 protected:
00333 Maybe<T> happened ;
00334 PipeEvents<T> * pred ;
00335
00336 protected:
00337
00338 void setDependency(void) { addDependency((DependencyUnit**)&pred); }
00339 ThisType * duplicate(void) const { return new ThisType(*this); }
00340
00341 public:
00342 PipeEventOnce( const PipeEvents<T>& x ) :
00343 happened(), pred(new PipeEvents<T>(x)) { setDependency(); }
00344 PipeEventOnce( const ThisType& e ) : BaseType(e),
00345 happened(e.happened), pred(e.pred) { setDependency(); }
00346
00347 Maybe<T> compute_local_fn( int fc )
00348 {
00349 if( !happened ) {
00350 happened = pred->get_value(fc);
00351 }
00352 return happened ;
00353 }
00354 };
00355
00356 template<class T>
00357 PipeEvents<T> onceP( const PipeEvents<T>& p ) {
00358 return PipeEvents<T>(new PipeEventOnce<T>(p));
00359 }
00360
00361 template<class T>
00362 class PipeEventNth : public PipeModule<Maybe<T> > {
00363 typedef PipeEventNth<T> ThisType ;
00364 typedef PipeModule<Maybe<T> > BaseType ;
00365 protected:
00366 int n, c ;
00367 PipeEvents<T> * pred ;
00368
00369 protected:
00370
00371 void setDependency(void) { addDependency((DependencyUnit**)&pred); }
00372 ThisType * duplicate(void) const { return new ThisType(*this); }
00373
00374 protected:
00375
00376 void check(void) { PipeModule<Maybe<T> >::check( pred ); }
00377
00378 public:
00379 PipeEventNth( int nth ) : n(nth), c(0), pred(0) { setDependency(); }
00380 PipeEventNth( const ThisType& e ) : BaseType(e),
00381 n(e.n), c(e.c), pred(e.pred) { setDependency(); }
00382
00383 PipeEvents<T> operator ()( const PipeEvents<T>& x ) const
00384 {
00385 PipeEventNth<T> *p = new PipeEventNth<T>(*this);
00386 p->pred = new PipeEvents<T>(x);
00387 return PipeEvents<T>(p);
00388 }
00389
00390 Maybe<T> compute_local_fn( int fc )
00391 {
00392 check();
00393 if( c < n && pred->get_value(fc) && ++c == n ) {
00394 return pred->get_value(fc);
00395 }else {
00396 return Maybe<T>();
00397 }
00398 }
00399 };
00400
00401 template<class T>
00402 PipeEventNth<T> nthP( int n ) {
00403 return PipeEventNth<T>(n);
00404 }
00405 template<class T>
00406 inline PipeEvents<T>
00407 operator <<= ( const PipeEventNth<T>& m, const PipeEvents<T>& p ){
00408 return m(p);
00409 }
00410
00411 00412 00413 00414 00415 00416 00417 00418 00419 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 00430 00431 00432 00433 00434 00435 00436 00437 00438 00439 00440 00441 00442 00443 00444 00445 00446 00447 00448 00449 00450 00451 00452 00453 00454 00455 00456 00457 00458 00459 00460 00461 00462 00463 00464 00465 00466 00467 00468 00469 00470 00471 00472 00473 00474 00475 00476 00477 00478 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 00489 00490 00491 00492 00493 00494 00495 00496 00497 00498 00499 00500 00501 00502 00503 00504 00505 00506 00507 00508 00509 00510 00511 00512 00513 00514 00515 00516 00517 00518 00519 00520 00521 00522 00523 00524 00525 00526 00527 00528 00529 00530 00531 00532 00533 00534 00535 00536 00537 00538 00539 00540 00541 00542 00543 00544 00545 00546
00547
00548 # endif //_PIPEEVENTS_H_