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