00001 #ifndef __pipeswitcher_h_ 00002 #define __pipeswitcher_h_ 00003 00004 #include "PipeModules.h" 00005 00006 template <class T> 00007 class Maybe : Pair<Pipe<bool>,T> { 00008 public: 00009 Maybe(const Pipe<bool> &x, T &y) : Pair(x,y) {}; 00010 00011 bool has_value() const { return lval; }; 00012 T operator *() { assert(lval); return rval; }; 00013 }; 00014 00015 typedef Pipe<bool> boolP; 00016 00017 template<class T> 00018 class Event : Pipe<T> { 00019 00020 Pipe<T> *behavior; 00021 bool (*cond) (const int&); 00022 typedef bool (*bool_func)(const int&); 00023 00024 public: 00025 00026 Event() : Pipe() {} 00027 Event(Pipe<T> &x, bool (*y)(const int&)) : Pipe(), behavior(&x), cond(y) {} 00028 00029 bool has_value(const int& val) const { return cond(val); } 00030 Pipe<T>* get_behavior() { return behavior; } 00031 bool_func get_cond_func() { return cond; } 00032 operator Pipe<T>* *() { assert(cond); return behavior; } 00033 }; 00034 00035 template<class T> 00036 class PipeUntil : public PipeModule<T> { 00037 00038 Pipe<T> *current; 00039 Event<T> *pred; 00040 bool been_set; 00041 00042 protected: 00043 00044 inline void check(void) { PipeModule<T>::check( pred ); } 00045 00046 public: 00047 00048 PipeUntil(): PipeModule(), been_set(false) {} 00049 PipeUntil(Pipe<T> &x, Event<T>& e) : current(&x), pred(&e), been_set(false) {} 00050 00051 T compute_local_fn(int fc) { 00052 check(); 00053 T temp = current->get_value(fc); 00054 if (pred->has_value(fc) && been_set == false) { 00055 been_set = true; 00056 current = pred->get_behavior(); 00057 } 00058 return temp; 00059 } 00060 00061 void keepup( int fc ) { current->get_value(fc); } 00062 00063 operator Pipe<T> () const 00064 { return Pipe<T>(new PipeUntil<T>(*this)); } 00065 00066 Pipe<T> operator () (const Pipe<T>& x) const { 00067 PipeUntil *p = new PipeUntil<T>(); 00068 p->pred = new Event<T>(x, pred->get_cond_func()); 00069 return Event<T>(p); 00070 } 00071 }; 00072 00073 template <class T> 00074 class PipeSwitch: public PipeModule<T> { 00075 00076 const Pipe<T> *current; 00077 const Event<T> *evt; 00078 00079 public: 00080 00081 PipeSwitch(const Pipe<T>& p, Event<T>& e) : current(&p), evt(&e) {}; 00082 00083 Pipe<T> &operator () (Pipe<T> &x, Event<T> &y) const { 00084 PipeSwitch *temp = new PipeSwitch<T>(); 00085 Pipe<T> *tempp = new Pipe<T>(temp); 00086 temp->current = new Pipe<T>(&x); 00087 temp->evt = new Pipe<T>(&y); 00088 return *tempp; 00089 } 00090 00091 T compute_local_fn(int fc) { 00092 T temp = current->get_value(fc); 00093 if (((*evt)->get_value(fc)).has_value()) { 00094 current = *(evt->get_value(fc)); 00095 } 00096 return temp; 00097 } 00098 }; 00099 00100 #endif