PolyBoRi
CBidirectTermIter.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00013 //*****************************************************************************
00014 
00015 #ifndef polybori_iterators_CBidirectTermIter_h_
00016 #define polybori_iterators_CBidirectTermIter_h_
00017 
00018 // get standard header
00019 #include <stack>
00020 #include <utility>
00021 
00022 // include basic definitions
00023 #include <polybori/pbori_defs.h>
00024 
00025 // Get forward term iterator
00026 #include "CTermIter.h"
00027 
00028 BEGIN_NAMESPACE_PBORI
00029 
00030 template<class NavigatorType>
00031 class handle_else :
00032   public std::deque<NavigatorType> {
00033 public:
00034 
00035   typedef NavigatorType navigator_type;
00036   typedef std::deque<NavigatorType> base;
00037 
00038   void operator()(const navigator_type& navi) {
00039 
00040     while(!base::empty() && (*top() >= *navi) )
00041       base::pop_back();
00042 
00043     base::push_back(navi);
00044   }
00045   void push(const navigator_type& navi) { base::push_back(navi); }
00046   void pop() { base::pop_back(); }
00047 
00048   const navigator_type& top() const { return base::back(); };
00049 
00050   void append(const handle_else& rhs) {
00051     PBORI_ASSERT(base::empty() || rhs.empty() || ((**rhs.begin()) > (*top())) );
00052     base::insert(base::end(), rhs.begin(), rhs.end());
00053   }
00054 };
00055 
00056 #if 0
00057 
00063 template <class TermType, class NavigatorType, 
00064           class ForwardOp, class BackwardOp, 
00065           class TerminalValueOp = project_ith<2> >
00066 class CBidirectTermIter:
00067   public CTermIter<TermType, NavigatorType, 
00068                    ForwardOp, BackwardOp, 
00069                    TerminalValueOp, 
00070                    handle_else<NavigatorType> >{
00071 
00072 public:
00073 
00075   typedef TermType term_type;
00076 
00078   typedef NavigatorType navigator_type;
00079 
00081   typedef ForwardOp forwardop_type;
00082 
00084   typedef BackwardOp backwardop_type;
00085 
00087   typedef TerminalValueOp termvalop_type;
00088 
00090   typedef handle_else<navigator_type> elsehandle_type;
00091 
00093   typedef CBidirectTermIter<term_type, navigator_type, 
00094                     forwardop_type, backwardop_type, termvalop_type> self;
00095 
00097   typedef CTermIter<term_type, navigator_type, 
00098                     forwardop_type, backwardop_type, termvalop_type,
00099                     elsehandle_type> base;
00100 
00102 
00103   typedef std::bidirectional_iterator_tag iterator_category;
00104   typedef typename base::difference_type difference_type;
00105   typedef typename base::pointer pointer;
00106   typedef typename base::reference reference;
00108 
00110   using base::handleElse;
00111 
00113   CBidirectTermIter(): 
00114     base() {}
00115 
00117   CBidirectTermIter(navigator_type navi, 
00118             forwardop_type fop_ = forwardop_type(), 
00119             backwardop_type bop_ = backwardop_type(), 
00120             termvalop_type tvop_ = termvalop_type() ):
00121     base(navi, fop_, bop_, tvop_) {}
00122 
00124   CBidirectTermIter(navigator_type navi, dummy_iterator):
00125     base() { 
00126     if(navi.isValid()) {
00127       followElse(navi); 
00128       terminate(navi);
00129     }
00130  }
00131   
00133   CBidirectTermIter(const self& rhs):
00134     base(rhs) {};
00135 
00137   ~CBidirectTermIter() {};
00138 
00140   self& operator++() {
00141     base::operator++();
00142     return *this;
00143   }
00144 
00146   self operator++(int dummy) { 
00147     return base::operator++(dummy);
00148   };
00149 
00151   self& operator--() {
00152 
00153     if (!handleElse.empty()){
00154       navigator_type navi = handleElse.top();
00155       base::popToIndex(*navi);
00156 
00157 
00158       handleElse.pop();
00159       base::nextThen(navi);
00160 
00161       followElse(navi);
00162     }
00163     else
00164       base::clear();
00165     return *this;
00166   }
00167 
00169   self operator--(int) { 
00170     self tmp(*this); 
00171     operator--(); 
00172     return tmp;
00173   };
00174 
00175 protected:
00176 
00177 
00178   void followElse(navigator_type& navi) {
00179     while( !navi.isConstant() ) {       // if still in interior of a path
00180       if(!navi.elseBranch().isEmpty()) {
00181         handleElse.push(navi);
00182         navi.incrementElse();   // go in direction of last term, if possible
00183       }
00184       else
00185         base::nextThen(navi);
00186     }  
00187   }
00188 
00189 };
00190 
00191 #endif
00192 
00193 END_NAMESPACE_PBORI
00194 
00195 #endif