cursor.h

Go to the documentation of this file.
00001 /*
00002  * ASTL - the Automaton Standard Template Library.
00003  * C++ generic components for Finite State Automata handling.
00004  * Copyright (C) 2000-2006 Vincent Le Maout (vincent.lemaout@chello.fr).
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00024 #ifndef ASTL_CURSOR_H
00025 #define ASTL_CURSOR_H
00026 
00027 #include <vector>
00028 #include <functional>
00029 #include <list>
00030 #include <deque>
00031 #include <queue>
00032 #include <set>
00033 #include <iostream>
00034 #include <utility>
00035 
00036 using namespace std;
00037 #if !defined(__GNUG__) || __GNUG__ >= 3
00038 using namespace rel_ops;
00039 #endif
00040 
00041 namespace astl {
00042 
00053 template <typename DFA>
00054 class cursor : public cursor_concept
00055 {
00056 public:
00057   typedef cursor                    self;
00058   typedef cursor_concept            super;
00059   typedef typename DFA::state_type  state_type; 
00060   typedef typename DFA::char_type   char_type;  
00061   typedef typename DFA::tag_type    tag_type;   
00062   typedef typename DFA::char_traits char_traits; 
00063   typedef typename super::concept   concept;
00064 
00066   cursor() 
00067   { }
00068 
00071   cursor(const DFA &a) 
00072     : dfa(&a)
00073   { }
00074 
00077   cursor(const DFA &a, state_type p) 
00078     : dfa(&a), q(p)
00079   { }
00080 
00082   state_type src() const { return q; } 
00083 
00086   self& operator=(state_type p) {
00087     q = p;
00088     return *this;
00089   }
00090 
00093   bool operator==(const self &x) const { return q == x.q; }
00094 
00097   bool sink() const { return q == DFA::null_state; }
00098 
00100   state_type sink_state() const { return DFA::null_state; }
00101 
00104   bool forward(const char_type &a) {
00105     q = dfa->delta1(q, a);
00106     return !sink();
00107   }
00108 
00110   bool src_final() const { return dfa->final(q); }
00111 
00113   const tag_type& src_tag() const  { return dfa->tag(q); }
00114 
00117   bool exists(const char_type &a) const {
00118     return dfa->delta1(q, a) != DFA::null_state;
00119   }
00120 
00121 protected:
00122   const DFA *dfa;
00123   state_type q;
00124 };
00125 
00135 template <typename FA>
00136 class transition_cursor : public transition_cursor_concept
00137 {
00138 public:
00139   typedef transition_cursor         self;
00140   typedef transition_cursor_concept super;
00141   typedef typename FA::state_type  state_type; 
00142   typedef typename FA::char_type   char_type;  
00143   typedef typename FA::tag_type    tag_type;   
00144   typedef typename FA::char_traits char_traits; 
00145   typedef typename super::concept   concept;
00146 
00151   transition_cursor(const FA &a, state_type p)
00152     : fa(&a), q(p)
00153   { }
00154 
00156   transition_cursor(const FA &a)
00157     : fa(&a)
00158   { }
00159 
00161   transition_cursor()
00162   { }
00163 
00165   state_type src() const { return q; }
00166 
00170   self& operator=(state_type p) {
00171     q = p;
00172     return *this;
00173   }
00174 
00177   bool sink() const { return q == FA::null_state; }
00178 
00180   state_type sink_state() const { return FA::null_state;  }
00181 
00183   bool src_final() const { return fa->final(q);  }
00184 
00186   const tag_type& src_tag() const { return fa->tag(q);  }
00187 
00189   bool operator==(const self &x) const {
00190     return (q == x.q && transition == x.transition);
00191   }
00192 
00194   bool operator!=(const self &x) const { return !(*this == x); }
00195 
00199   char_type letter() const { return (*transition).first; }
00200 
00205   bool first() {
00206     return !((transition = fa->delta2(q).begin()) == fa->delta2(q).end());
00207   }
00208 
00215   bool next() { return !(++transition == fa->delta2(q).end()); }
00216 
00220   void forward() { q = (*transition).second; }
00221 
00225   state_type aim() const { return (*transition).second; }
00226 
00229   bool aim_final() const { return fa->final((*transition).second); }
00230 
00233   const tag_type& aim_tag() const { return fa->tag((*transition).second); }
00234 
00235   // Not a standard requirement:
00236   bool operator<(const self &x) const {
00237     return q < x.q || (q == x.q && transition < x.transition);
00238   }
00239 
00240 protected:
00241   const FA *fa;
00242   state_type q;
00243   typename FA::edges_type::const_iterator transition;
00244 };
00245 
00254 template <typename DFA>
00255 class forward_cursor
00256   : public transition_cursor<DFA>, public forward_cursor_concept
00257 {
00258 public:
00259   typedef forward_cursor<DFA>         self;
00260   typedef transition_cursor<DFA>      super;
00261   typedef typename DFA::state_type  state_type; 
00262   typedef typename DFA::char_type   char_type;  
00263   typedef typename DFA::tag_type    tag_type;   
00264   typedef typename DFA::char_traits char_traits; 
00265   typedef forward_cursor_concept      concept;
00266 
00268   forward_cursor(const DFA &a, state_type p)
00269     : super(a, p)
00270   { }
00271 
00274   forward_cursor(const DFA &a)
00275     : super(a)
00276   { }
00277 
00279   forward_cursor()
00280     : super()
00281   { }
00282 
00285   self& operator=(state_type p) {
00286     super::operator=(p);
00287     return *this;
00288   }
00289 
00293   bool forward(const char_type &a) {
00294     q = fa->delta1(q, a);
00295     return !this->sink();
00296   }
00297 
00301   void forward() { q = (*transition).second; }
00302 
00305   bool exists(const char_type &a) const {
00306     return fa->delta1(q, a) != DFA::null_state;
00307   }
00308 
00313   bool find(const char_type &a)  {
00314     return !((transition = fa->delta2(q).find(a)) == fa->delta2(q).end());
00315   }
00316 
00317 protected:
00318   typedef typename DFA::edges_type::const_iterator edges_iterator;
00319   using super::q;
00320   using super::fa;
00321   using super::transition;
00322 };
00323 
00340 template <typename ForwardCursor, typename StackContainer = vector<ForwardCursor> >
00341 class stack_cursor
00342   : public StackContainer, public stack_cursor_concept
00343 {
00344   // the interface publicly inherited from stack is not a standard requirement
00345 public:
00346   typedef stack_cursor                        self;
00347   typedef StackContainer                      super;
00348   typedef typename ForwardCursor::state_type  state_type; 
00349   typedef typename ForwardCursor::char_type   char_type;  
00350   typedef typename ForwardCursor::tag_type    tag_type;   
00351   typedef typename ForwardCursor::char_traits char_traits; 
00352   typedef stack_cursor_concept                concept;
00353 
00355   stack_cursor(const ForwardCursor &x)
00356     : super() {
00357     push_back(x);
00358   }
00359 
00361   stack_cursor()  // Empty stack
00362     : super()
00363   { }
00364 
00368   state_type src() const { return super::back().src(); }
00369 
00374   state_type aim() const { return super::back().aim(); }
00375 
00380   char_type letter() const { return super::back().letter(); }
00381 
00384   bool sink() const { return super::back().sink(); }
00385 
00388   state_type sink_state() const { return super::back().sink_state(); }
00389 
00392   bool exists(const char_type &a) const { return super::back().exists(a); }
00393 
00397   bool find(const char_type &a) { return super::back().find(a); }
00398 
00403   bool first() { return super::back().first(); }
00404 
00412   bool next() { return super::back().next(); }
00413 
00419   void forward() {
00420     push_back(super::back());
00421     super::back().forward();
00422   }
00423 
00427   bool forward(const char_type &a) {
00428     push_back(super::back());
00429     return super::back().forward(a);
00430   }
00431 
00434   bool backward() {
00435     super::pop_back();
00436     return !super::empty();
00437   }
00438 
00441   bool aim_final() const { return super::back().aim_final(); }
00442 
00445   bool src_final() const { return super::back().src_final(); }
00446 
00449   tag_type src_tag() const { return super::back().src_tag(); }
00450 
00453   tag_type aim_tag() const { return super::back().aim_tag(); }
00454 
00456   const ForwardCursor& top() const { return super::back(); }
00457 };
00458 
00459 struct none
00460 {
00461   template <class T>
00462   bool operator()(const T&) const {
00463     return false;
00464   }
00465 };
00466 
00491 template <typename StackCursor, typename MarkerFunction = none>
00492 class dfirst_cursor : public dfirst_cursor_concept
00493 {
00494 protected:
00495   StackCursor c;
00496   bool has_poped;
00497   MarkerFunction visited;
00498 
00499 public:
00500   typedef dfirst_cursor                     self;
00501   typedef dfirst_cursor_concept             super;
00502   typedef typename StackCursor::state_type  state_type; 
00503   typedef typename StackCursor::char_type   char_type;  
00504   typedef typename StackCursor::tag_type    tag_type;   
00505   typedef typename StackCursor::char_traits char_traits; 
00506   typedef typename super::concept           concept;
00507 
00509   dfirst_cursor(const StackCursor &x,
00510                 const MarkerFunction &f = MarkerFunction())
00511     : c(x), has_poped(false), visited(f) {
00512     visited(c.src());   // set c source to 'visited'
00513   }
00514 
00517   dfirst_cursor()
00518     : c(), has_poped(false)
00519   { }
00520 
00524   bool forward() {
00525     if (has_poped) { 
00526       // move on to the next outgoing transition if any otherwise pop
00527       if (!c.next()) 
00528         return !c.backward();  // at edges end
00529       else {
00530         has_poped = false;
00531         return true;
00532       }
00533     }
00534 
00535     c.forward();
00536     if (visited(c.src()) || !c.first()) {
00537       c.backward(); // cannot forward so backward => pop
00538       has_poped = true;
00539       return false;
00540     }
00541     return true;
00542   }
00543 
00546   void backward() { has_poped = true; } // force pop
00547 
00550   char_type letter() const { return c.letter(); }
00551 
00555   bool aim_final() const { return c.aim_final(); }
00556 
00559   bool src_final() const { return c.src_final(); }
00560 
00563   state_type src() const { return c.src(); }
00564 
00567   state_type aim() const { return c.aim(); }
00568 
00570   bool operator==(const self &x) const { return c == x.c; }
00571 
00573   bool operator!=(const self &x) const { return !(*this == x); }
00574 
00577   tag_type src_tag() const { return c.src_tag(); }
00578 
00581   tag_type aim_tag() const { return c.aim_tag(); }
00582 
00584   const StackCursor& stack() const { return c; }
00585 };
00586 
00587 template <class state_type, class LessThan = less<state_type> >
00588 struct set_marker : unary_function<state_type, bool>
00589 {
00590   set<state_type, LessThan> pool;
00591   set_marker()
00592   { }
00593   bool operator() (const state_type &q) {
00594     return !(pool.insert(q).second);  // insert returns pair<iterator,bool>
00595   }
00596 };
00597 
00604 template <typename DFA>
00605 inline
00606 cursor<DFA> plainc(const DFA &a, typename DFA::state_type q) {
00607   return cursor<DFA>(a, q);
00608 }
00609 
00615 template <typename DFA>
00616 inline
00617 cursor<DFA> plainc(const DFA &a) {
00618   return cursor<DFA>(a, a.initial());
00619 }
00620 
00627 template <typename FA>
00628 inline
00629 transition_cursor<FA> transitionc(const FA &a, typename FA::state_type q) {
00630   return transition_cursor<FA>(a, q);
00631 }
00632 
00637 template <typename FA>
00638 inline
00639 transition_cursor<FA> transitionc(const FA &a) {
00640   return transition_cursor<FA>(a, a.initial());
00641 }
00642 
00649 template <typename DFA>
00650 inline
00651 forward_cursor<DFA> forwardc(const DFA &a, typename DFA::state_type q) {
00652   return forward_cursor<DFA>(a, q);
00653 }
00654 
00659 template <typename DFA>
00660 inline
00661 forward_cursor<DFA> forwardc(const DFA &a) {
00662   return forward_cursor<DFA>(a, a.initial());
00663 }
00664 
00669 template <typename ForwardCursor>
00670 inline
00671 stack_cursor<ForwardCursor> stackc(const ForwardCursor &c) {
00672   return stack_cursor<ForwardCursor>(c);
00673 }
00674 
00675 // default behavior (catch-all):
00676 template <typename Model, typename Concept>
00677 struct dfirst_cursor_type
00678 {
00679   // Trick: this template does not define a public 'model'
00680   // type. Instanciation of this template will occur if no
00681   // specialization exists and will lead to a compiler error
00682   // which means that Model is not either a FA, DFA, forward_cursor,
00683   // transition_cursor nor a stack_cursor and therefore cannot be used
00684   // to instanciate the function template dfirstc
00685 };
00686 
00687 template <class FA>
00688 struct dfirst_cursor_type<FA, FA_concept>
00689 {
00690   typedef dfirst_cursor<stack_cursor<transition_cursor<FA> > > model;
00691 };
00692 
00693 template <class DFA>
00694 struct dfirst_cursor_type<DFA, DFA_concept>
00695 {
00696   typedef dfirst_cursor<stack_cursor<forward_cursor<DFA> > > model;
00697 };
00698 
00699 template <class ForwardCursor>
00700 struct dfirst_cursor_type<ForwardCursor, forward_cursor_concept>
00701 {
00702   typedef dfirst_cursor<stack_cursor<ForwardCursor> > model;
00703 };
00704 
00705 template <class TransitionCursor>
00706 struct dfirst_cursor_type<TransitionCursor, transition_cursor_concept>
00707 {
00708   typedef dfirst_cursor<stack_cursor<TransitionCursor> > model;
00709 };
00710 
00711 template <class StackCursor>
00712 struct dfirst_cursor_type<StackCursor, stack_cursor_concept>
00713 {
00714   typedef dfirst_cursor<StackCursor> model;
00715 };
00716 
00725 template <typename T>
00726 inline
00727 typename dfirst_cursor_type<T, typename T::concept>::model
00728 dfirstc(const T &x)
00729 {
00730   return dfirstc_(x, x);
00731 }
00732 
00733 // Builds a depth first cursor from a DFA pointing to the first
00734 // outgoing transition of the initial state if any by constructing the
00735 // underlying forward and stack cursors. If the DFA has no initial
00736 // state or if it has no outgoing transitions, returns an empty cursor
00737 template <typename DFA>
00738 typename dfirst_cursor_type<DFA, DFA_concept>::model
00739 dfirstc_(const DFA &x, DFA_concept)
00740 {
00741   forward_cursor<DFA> fc(x, x.initial());
00742   if (!fc.sink() && fc.first())
00743     return dfirst_cursor<stack_cursor<forward_cursor<DFA> > >(stackc(fc));
00744   else
00745     return dfirst_cursor<stack_cursor<forward_cursor<DFA> > >();
00746 }
00747 
00748 template <typename FA>
00749 typename dfirst_cursor_type<FA, FA_concept>::model
00750 dfirstc_(const FA &x, FA_concept)
00751 {
00752   transition_cursor<FA> fc(x, x.initial());
00753   if (!fc.sink() && fc.first())
00754     return dfirst_cursor<stack_cursor<transition_cursor<FA> > >(stackc(fc));
00755   else
00756     return dfirst_cursor<stack_cursor<transition_cursor<FA> > >();
00757 }
00758 
00759 // Builds a depth first cursor from a forward cursor by constructing the
00760 // underlying stack cursor:
00761 template <class ForwardCursor>
00762 typename dfirst_cursor_type<ForwardCursor, forward_cursor_concept>::model
00763 dfirstc_(const ForwardCursor &x, forward_cursor_concept)
00764 {
00765   if (!x.sink()) {
00766     stack_cursor<ForwardCursor> s(x);
00767     if (s.first())
00768       return dfirst_cursor<stack_cursor<ForwardCursor> >(s);
00769   }
00770   return dfirst_cursor<stack_cursor<ForwardCursor> >();
00771 }
00772 
00773 // Builds a depth first cursor from a transition cursor by constructing the
00774 // underlying stack cursor:
00775 template <class TransitionCursor>
00776 typename dfirst_cursor_type<TransitionCursor, transition_cursor_concept>::model
00777 dfirstc_(const TransitionCursor &x, transition_cursor_concept)
00778 {
00779   if (!x.sink()) {
00780     stack_cursor<TransitionCursor> s(x);
00781     if (s.first())
00782       return dfirst_cursor<stack_cursor<TransitionCursor> >(s);
00783   }
00784   return dfirst_cursor<stack_cursor<TransitionCursor> >();
00785 }
00786 
00787 // Builds a depth first cursor from a stack cursor:
00788 template <class StackCursor>
00789 typename dfirst_cursor_type<StackCursor, stack_cursor_concept>::model
00790 dfirstc_(const StackCursor &x, stack_cursor_concept)
00791 {
00792   if (!x.sink()) {
00793     StackCursor s(x);
00794     if (s.first()) return dfirst_cursor<StackCursor>(s);
00795   }
00796   return dfirst_cursor<StackCursor>();
00797 }
00798 
00799 // Depth first mark cursor helper functions:
00800 template <typename Model, typename Concept, typename MarkerFunction>
00801 struct dfirst_mark_cursor_type
00802 { };
00803 
00804 template <typename DFA, typename MarkerFunction>
00805 struct dfirst_mark_cursor_type<DFA, DFA_concept, MarkerFunction>
00806 {
00807   typedef dfirst_cursor<stack_cursor<forward_cursor<DFA> >,
00808                         MarkerFunction> model;
00809 };
00810 
00811 template <typename FA, typename MarkerFunction>
00812 struct dfirst_mark_cursor_type<FA, FA_concept, MarkerFunction>
00813 {
00814   typedef dfirst_cursor<stack_cursor<transition_cursor<FA> >,
00815                         MarkerFunction> model;
00816 };
00817 
00818 template <typename TransitionCursor, typename MarkerFunction>
00819 struct dfirst_mark_cursor_type<TransitionCursor, transition_cursor_concept,
00820                                MarkerFunction>
00821 {
00822   typedef dfirst_cursor<stack_cursor<TransitionCursor>, MarkerFunction> model;
00823 };
00824 
00825 template <typename ForwardCursor, typename MarkerFunction>
00826 struct dfirst_mark_cursor_type<ForwardCursor, forward_cursor_concept,
00827                                MarkerFunction>
00828 {
00829   typedef dfirst_cursor<stack_cursor<ForwardCursor>, MarkerFunction> model;
00830 };
00831 
00843 template <typename T>
00844 inline
00845 typename dfirst_mark_cursor_type<T, typename T::concept,
00846                                  set_marker<typename T::state_type> >::model
00847 dfirst_markc(const T &x)
00848 {
00849   return dfirst_markc_(x, x, set_marker<typename T::state_type>());
00850 }
00851 
00852 template <typename T, typename MarkerFunction>
00853 inline
00854 typename dfirst_mark_cursor_type<T, typename T::concept, MarkerFunction>::model
00855 dfirst_markc(const T &x, const MarkerFunction& m)
00856 {
00857   return dfirst_markc_(x, x, m);
00858 }
00859 
00860 // Build a depth first cursor from a DFA pointing to the first
00861 // outgoing transition of the initial state (if any) by constructing
00862 // the underlying forward and stack cursors. If the DFA has no initial
00863 // state or if it has no outgoing transition, return an empty cursor
00864 template <typename DFA, typename MarkerFunction>
00865 typename dfirst_mark_cursor_type<DFA, DFA_concept, MarkerFunction>::model
00866 dfirst_markc_(const DFA &x, DFA_concept, const MarkerFunction& m)
00867 {
00868   forward_cursor<DFA> fc(x, x.initial());
00869   if (!fc.sink() && fc.first())
00870     return dfirst_cursor<stack_cursor<forward_cursor<DFA> >,
00871       MarkerFunction>(stackc(fc), m);
00872   else
00873     return dfirst_cursor<stack_cursor<forward_cursor<DFA> >,
00874       MarkerFunction>();
00875 }
00876 
00877 template <typename FA, typename MarkerFunction>
00878 typename dfirst_mark_cursor_type<FA, FA_concept, MarkerFunction>::model
00879 dfirst_markc_(const FA &x, FA_concept, const MarkerFunction& m)
00880 {
00881   transition_cursor<FA> fc(x, x.initial());
00882   if (!fc.sink() && fc.first())
00883     return dfirst_cursor<stack_cursor<transition_cursor<FA> >,
00884       MarkerFunction>(stackc(fc), m);
00885   else
00886     return dfirst_cursor<stack_cursor<transition_cursor<FA> >,
00887       MarkerFunction>();
00888 }
00889 
00890 // Builds a depth first cursor from a forward cursor by constructing
00891 // the underlying stack cursor:
00892 template <typename ForwardCursor, typename MarkerFunction>
00893 typename dfirst_mark_cursor_type<ForwardCursor, forward_cursor_concept,
00894                                  MarkerFunction>::model
00895 dfirst_markc_(const ForwardCursor &x, forward_cursor_concept,
00896               const MarkerFunction& m)
00897 {
00898   if (!x.sink()) {
00899     stack_cursor<ForwardCursor> s(x);
00900     if (s.first())
00901       return dfirst_cursor<stack_cursor<ForwardCursor>, MarkerFunction>(s, m);
00902   }
00903   return dfirst_cursor<stack_cursor<ForwardCursor>, MarkerFunction>();
00904 }
00905 
00906 // Builds a depth first cursor from a transition cursor by
00907 // constructing the underlying stack cursor:
00908 template <typename TransitionCursor, typename MarkerFunction>
00909 typename dfirst_mark_cursor_type<TransitionCursor, transition_cursor_concept,
00910                                  MarkerFunction>::model
00911 dfirst_markc_(const TransitionCursor &x, transition_cursor_concept,
00912               const MarkerFunction& m)
00913 {
00914   if (!x.sink()) {
00915     stack_cursor<TransitionCursor> s(x);
00916     if (s.first())
00917       return dfirst_cursor<stack_cursor<TransitionCursor>,
00918         MarkerFunction>(s, m);
00919   }
00920   return dfirst_cursor<stack_cursor<TransitionCursor>, MarkerFunction>();
00921 }
00922 
00938 template <typename ForwardCursor, typename QueueContainer = deque<ForwardCursor> >
00939 class queue_cursor
00940   : public QueueContainer, public queue_cursor_concept
00941 {
00942 public:
00943   typedef queue_cursor                        self;
00944   typedef QueueContainer                      super;
00945   typedef typename ForwardCursor::state_type  state_type; 
00946   typedef typename ForwardCursor::char_type   char_type;  
00947   typedef typename ForwardCursor::tag_type    tag_type;   
00948   typedef typename ForwardCursor::char_traits char_traits; 
00951   queue_cursor(const ForwardCursor &x)
00952     : super() {
00953     super::push_back(x);
00954   }
00955 
00957   queue_cursor()
00958     : super()
00959   { }
00960 
00963   state_type src() const { return super::back().src(); }
00964 
00969   state_type aim() const { return super::back().aim(); }
00970 
00973   bool src_final() const { return super::back().src_final();  }
00974 
00977   bool aim_final() const { return super::back().aim_final();  }
00978 
00983   char_type letter() const { return super::back().letter();  }
00984 
00987   bool sink() const { return super::back().sink();  }
00988 
00989   state_type sink_state() const { return super::back().sink_state(); }
00990 
00992   bool find(const char_type &a) { return super::back().find(a); }
00993 
00999   bool first() { return super::back().first(); }
01000 
01008   bool next() { 
01009     super::push_back(super::back());
01010     return super::back().next();
01011   }
01012 
01017   void forward() { super::back().forward(); }
01018 
01022   bool forward(const char_type &a) { return super::back().forward(a); }
01023 
01026   bool exists(const char_type &a) const { return super::back().exists(a); }
01027 
01030   bool dequeue() {
01031     super::back() = super::front();
01032     super::pop_back();
01033     return !super::empty();
01034   }
01035 
01038   tag_type src_tag() const { return super::back().src_tag(); }
01039 
01042   tag_type aim_tag() const { return super::back().aim_tag(); }
01043 };
01044 
01045 
01066 template <typename QueueCursor, typename MarkerFunction = none>
01067 class bfirst_cursor : public bfirst_cursor_concept
01068 {
01069 protected:
01070   QueueCursor c;
01071   MarkerFunction visited;
01072 
01073 public:
01074   typedef bfirst_cursor                     self;
01075   typedef typename QueueCursor::state_type  state_type; 
01076   typedef typename QueueCursor::char_type   char_type;  
01077   typedef typename QueueCursor::tag_type    tag_type;   
01078   typedef typename QueueCursor::char_traits char_traits; 
01079   typedef bfirst_cursor_concept             concept;
01080 
01082   bfirst_cursor(const QueueCursor &x,
01083                 const MarkerFunction &f = MarkerFunction())
01084     : c(x), visited(f) {
01085     visited(c.src());
01086   }
01087 
01090   bfirst_cursor()
01091     : c()
01092   { }
01093 
01097   bool next() {
01098     if (!c.next()) {
01099       while (c.dequeue()) {
01100         c.forward();
01101         if (!visited(c.src()) && c.first()) break;
01102       }
01103       return false;
01104     }
01105     return true;
01106   }
01107 
01110   state_type src() const { return c.src(); }
01111 
01114   state_type aim() const { return c.aim(); }
01115 
01118   bool src_final() const { return c.src_final(); }
01119 
01123   bool aim_final() const { return c.aim_final(); }
01124 
01127   char_type letter() const { return c.letter(); }
01128 
01131   bool operator==(const self &x) const { return c == x.c; }
01132 
01135   bool operator!=(const self &x) const { return !(*this == x); }
01136 
01139   tag_type src_tag() const { return c.src_tag(); }
01140 
01143   tag_type aim_tag() const { return c.aim_tag(); }
01144 };
01145 
01149 template <class ForwardCursor>
01150 queue_cursor<ForwardCursor> queuec(const ForwardCursor &x) {
01151   return queue_cursor<ForwardCursor>(x);
01152 }
01153 
01154 template <class Model, class Concept>
01155 struct bfirst_cursor_type
01156 { };
01157 
01158 template <class DFA>
01159 struct bfirst_cursor_type<DFA, DFA_concept>
01160 {
01161   typedef bfirst_cursor<queue_cursor<forward_cursor<DFA> > > model;
01162 };
01163 
01164 template <class TransitionCursor>
01165 struct bfirst_cursor_type<TransitionCursor, transition_cursor_concept>
01166 {
01167   typedef bfirst_cursor<queue_cursor<TransitionCursor> > model;
01168 };
01169 
01170 template <class ForwardCursor>
01171 struct bfirst_cursor_type<ForwardCursor, forward_cursor_concept>
01172 {
01173   typedef bfirst_cursor<queue_cursor<ForwardCursor> > model;
01174 };
01175 
01176 template <class QueueCursor>
01177 struct bfirst_cursor_type<QueueCursor, queue_cursor_concept>
01178 {
01179   typedef bfirst_cursor<QueueCursor> model;
01180 };
01181 
01190 template <typename T>
01191 inline
01192 typename bfirst_cursor_type<T, typename T::concept>::model
01193 bfirstc(const T &x) {
01194   return _bfirstc(x, x);
01195 }
01196 
01197 // Builds a breadth-first cursor from a DFA pointing to the first
01198 // outgoing transition of the initial state if any by constructing the
01199 // underlying forward and stack cursors. If the DFA has no initial
01200 // state or if it has no outgoing transitions, returns an empty cursor
01201 template <class DFA>
01202 inline
01203 typename bfirst_cursor_type<DFA, DFA_concept>::model
01204 _bfirstc(const DFA &x, DFA_concept)
01205 {
01206   forward_cursor<DFA> fc(x, x.initial());
01207   if (!fc.sink() && fc.first())
01208     return bfirst_cursor<queue_cursor<forward_cursor<DFA> > >(queuec(fc));
01209   else
01210     return bfirst_cursor<queue_cursor<forward_cursor<DFA> > >();
01211 }
01212 
01213 // Builds a breadth-first cursor from a transition cursor by constructing
01214 // the underlying stack cursor:
01215 template <class TransitionCursor>
01216 inline
01217 typename bfirst_cursor_type<TransitionCursor, transition_cursor_concept>::model
01218 _bfirstc(const TransitionCursor &x, transition_cursor_concept)
01219 {
01220   if (!x.sink()) {
01221     queue_cursor<TransitionCursor> s(x);
01222     if (s.first())
01223       return bfirst_cursor<queue_cursor<TransitionCursor> >(s);
01224   }
01225   return bfirst_cursor<queue_cursor<TransitionCursor> >();
01226 }
01227 
01228 // Builds a breadth-first cursor from a forward cursor by constructing
01229 // the underlying stack cursor:
01230 template <class ForwardCursor>
01231 inline
01232 typename bfirst_cursor_type<ForwardCursor, forward_cursor_concept>::model
01233 _bfirstc(const ForwardCursor &x, forward_cursor_concept)
01234 {
01235   if (!x.sink()) {
01236     queue_cursor<ForwardCursor> s(x);
01237     if (s.first())
01238       return bfirst_cursor<queue_cursor<ForwardCursor> >(s);
01239   }
01240   return bfirst_cursor<queue_cursor<ForwardCursor> >();
01241 }
01242 
01243 // Builds a breadth-first cursor from a stack cursor:
01244 template <class QueueCursor>
01245 inline
01246 typename bfirst_cursor_type<QueueCursor, queue_cursor_concept>::model
01247 _bfirstc(const QueueCursor &x, queue_cursor_concept)
01248 {
01249   if (!x.sink()) {
01250     QueueCursor s(x);
01251     if (s.first())
01252       return bfirst_cursor<QueueCursor>(s);
01253   }
01254   return bfirst_cursor<QueueCursor>();
01255 }
01256 
01257 template <class Model, class Concept, typename MarkerFunction>
01258 struct bfirst_mark_cursor_type
01259 { };
01260 
01261 template <class DFA, typename MarkerFunction>
01262 struct bfirst_mark_cursor_type<DFA, DFA_concept, MarkerFunction>
01263 {
01264   typedef bfirst_cursor<queue_cursor<forward_cursor<DFA> >,
01265                         MarkerFunction> model;
01266 };
01267 
01268 template <class ForwardCursor, typename MarkerFunction>
01269 struct bfirst_mark_cursor_type<ForwardCursor, forward_cursor_concept,
01270                                MarkerFunction>
01271 {
01272   typedef bfirst_cursor<queue_cursor<ForwardCursor>, MarkerFunction > model;
01273 };
01274 
01275 template <class QueueCursor, typename MarkerFunction>
01276 struct bfirst_mark_cursor_type<QueueCursor, queue_cursor_concept,
01277                                MarkerFunction>
01278 {
01279   typedef bfirst_cursor<QueueCursor, MarkerFunction> model;
01280 };
01281 
01291 template <class T>
01292 inline
01293 typename bfirst_mark_cursor_type<T, typename T::concept,
01294                                  set_marker<typename T::state_type> >::model
01295 bfirst_markc(const T &x) {
01296   return bfirst_markc_(x, x, set_marker<typename T::state_type>());
01297 }
01298 
01299 template <class T, typename MarkerFunction>
01300 inline
01301 typename bfirst_mark_cursor_type<T, typename T::concept,
01302                                  MarkerFunction>::model
01303 bfirst_markc(const T &x, const MarkerFunction& m) {
01304   return bfirst_markc_(x, x, m);
01305 }
01306 
01307 // Builds a breadth-first mark cursor from a DFA pointing to the first
01308 // outgoing transition of the initial state if any by constructing the
01309 // underlying forward and stack cursors. If the DFA has no initial
01310 // state or if it has no outgoing transitions, returns an empty cursor
01311 template <class DFA, typename MarkerFunction>
01312 inline
01313 typename bfirst_mark_cursor_type<DFA, DFA_concept, MarkerFunction>::model
01314 bfirst_markc_(const DFA &x, DFA_concept, const MarkerFunction& m)
01315 {
01316   forward_cursor<DFA> fc(x, x.initial());
01317   if (!fc.sink() && fc.first())
01318     return bfirst_cursor<queue_cursor<forward_cursor<DFA> >,
01319       MarkerFunction >(queuec(fc),m);
01320   else
01321     return bfirst_cursor<queue_cursor<forward_cursor<DFA> >,
01322       MarkerFunction >();
01323 }
01324 
01325 // Builds a breadth-first mark cursor from a forward cursor by constructing
01326 // the underlying stack cursor:
01327 template <class ForwardCursor, typename MarkerFunction>
01328 inline
01329 typename bfirst_mark_cursor_type<ForwardCursor, forward_cursor_concept,
01330                                  MarkerFunction>::model
01331 bfirst_markc_(const ForwardCursor &x, forward_cursor_concept,
01332               const MarkerFunction& m)
01333 {
01334   if (!x.sink()) {
01335     queue_cursor<ForwardCursor> s(x);
01336     if (s.first())
01337       return bfirst_cursor<queue_cursor<ForwardCursor>,
01338         MarkerFunction>(s, m);
01339   }
01340   return bfirst_cursor<queue_cursor<ForwardCursor>, MarkerFunction>();
01341 }
01342 
01343 // Builds a breadth-first cursor from a stack cursor:
01344 template <class QueueCursor, typename MarkerFunction>
01345 inline
01346 typename bfirst_mark_cursor_type<QueueCursor, queue_cursor_concept,
01347                                  MarkerFunction>::model
01348 bfirst_markc_(const QueueCursor &x, queue_cursor_concept,
01349               const MarkerFunction& m)
01350 {
01351   if (!x.sink()) {
01352     QueueCursor s(x);
01353     if (s.first())
01354       return bfirst_cursor<QueueCursor, MarkerFunction>(s, m);
01355   }
01356   return bfirst_cursor<QueueCursor, MarkerFunction>();
01357 }
01358 
01367 template <typename Cursor, typename InputIterator>
01368 inline
01369 bool forward(Cursor &c, InputIterator i, InputIterator j) {
01370   for(; !(i == j) && c.forward(*i); ++i);
01371   return i == j;
01372 }
01373 
01374 } // namespace astl
01375 
01376 #endif  // ASTL_CURSOR_H
01377 
01378 
01379 
01380 
01381 
01382 
01383 
01384 
01385 
01386 
01387 
01388 
01389 
01390 
01391 
01392 

Generated on Sun Mar 8 02:41:31 2009 for ASTL by  doxygen 1.5.7.1