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