filter.h

00001 /*
00002  * ASTL - the Automaton Standard Template Library.
00003  * C++ generic components for Finite State Automata handling.
00004  * Copyright (C) 2000-2003 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 
00022 #ifndef ASTL_FILTER_H
00023 #define ASTL_FILTER_H
00024 
00025 
00026 
00027 namespace astl {
00028 
00029 template <class ForwardCursor, class ObjectFunction>
00030 class filter_in_cursor : public ForwardCursor
00031 {
00032 public:
00033   typedef filter_in_cursor            self;
00034   typedef ForwardCursor               super;
00035   typedef typename super::state_type  state_type;
00036   typedef typename super::char_type   char_type;
00037   typedef typename super::char_traits char_traits;
00038   typedef forward_cursor_concept      concept;
00039   typedef typename super::tag_type    tag_type;
00040 
00041   filter_in_cursor(const super &x = super(), 
00042                    const ObjectFunction &of = ObjectFunction())
00043     : super(x), f(of)
00044   { }
00045 
00046   void forward() {
00047     super::forward();
00048   }
00049 
00050   bool forward(const char_type &a) {
00051     return super::forward(f(a));
00052   }
00053 
00054   bool find(const char_type &a) {
00055     return super::find(f(a));
00056   }
00057 
00058   self& operator=(const state_type &x) {
00059     super::operator=(x);
00060     return *this;
00061   }
00062 
00063 protected:
00064   ObjectFunction f;
00065 };
00066 
00067 
00068 template <class ForwardCursor, class ObjectFunction>
00069 class filter_out_cursor : public ForwardCursor
00070 {
00071 protected:
00072   ObjectFunction f;
00073 
00074 public:
00075   typedef filter_out_cursor                    self;
00076   typedef ForwardCursor                        super;
00077   typedef typename ObjectFunction::result_type char_type;
00078   typedef typename super::state_type           state_type;
00079 
00080   filter_out_cursor(const super &x, 
00081                     const ObjectFunction &of = ObjectFunction())
00082     : super(x), f(of)
00083   { }
00084 
00085   char_type letter() const {
00086     return f(super::letter());
00087   }
00088 };
00089 
00090 // A filter cursor hides the transitions (q, a, p) which do not verify
00091 // a given predicate. The predicate takes a forward cursor as
00092 // argument and returns true if the pointed transition is "viewable"
00093 template <typename ForwardCursor, typename Predicate>
00094 class filter_cursor : public ForwardCursor
00095 {
00096 protected:
00097   Predicate p;
00098 
00099 public:
00100   typedef ForwardCursor              super;
00101   typedef filter_cursor              self;
00102   typedef typename super::char_type  char_type;
00103   typedef typename super::state_type state_type;
00104 
00105   filter_cursor(const ForwardCursor &x, 
00106                 const Predicate &pr = Predicate()) 
00107     : super(x), p(pr)
00108   { }
00109 
00110   bool exists(const char_type &c) const {
00111     if (!super::exists(c)) return false; // useful optimization ?
00112     self tmp = *this;
00113     return tmp.find(c);
00114   }
00115 
00116   bool find(const char_type &c) {
00117     return super::find(c) && p(*this);
00118   }
00119 
00120   bool forward(const char_type &c) {
00121     if (find(c)) forward();
00122     else *this = super::sink_state();
00123     return !super::sink();
00124   }
00125 
00126   bool first() {
00127     return super::first() && (p(*this) || super::next());
00128   }
00129 
00130   bool next() {
00131     while (super::next())
00132       if (p(*this)) return true;
00133     return false;
00134   }
00135 
00136   self& operator=(const state_type &q) {
00137     super::x = q;
00138     return *this;
00139   }
00140 
00141   self& operator=(const self &s) {
00142     super::x = s.x;
00143     return *this;
00144   }
00145 
00146   // warning: s may point to an invalid transition (p(s) == false)
00147   self& operator=(const super &s) {
00148     super::x = s;
00149     return *this;
00150   }
00151 };
00152 
00153 // Helper functions:
00154 template <typename ForwardCursor, typename ObjectFunction>
00155 inline
00156 filter_out_cursor<ForwardCursor, ObjectFunction>
00157 filter_outc(const ForwardCursor &x, const ObjectFunction &f) {
00158   return filter_out_cursor<ForwardCursor, ObjectFunction>(x, f);
00159 }
00160 
00161 template <typename ForwardCursor, typename ObjectFunction>
00162 inline
00163 filter_in_cursor<ForwardCursor, ObjectFunction>
00164 filter_inc(const ForwardCursor &x, const ObjectFunction &f) {
00165   return filter_in_cursor<ForwardCursor, ObjectFunction>(x, f);
00166 }
00167 
00168 template <typename ForwardCursor, typename Predicate>
00169 inline
00170 filter_cursor<ForwardCursor, Predicate>
00171 filterc(const ForwardCursor &x, const Predicate &pr) {
00172   return filter_cursor<ForwardCursor, Predicate>(x, pr);
00173 }
00174 
00175 } // namespace astl
00176 
00177 #endif // ASTL_FILTER_H
00178 
00179 
00180 

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