filters.hpp

Go to the documentation of this file.
00001 #ifndef wali_nwa_query_details_FILTER_HPP
00002 #define wali_nwa_query_details_FILTER_HPP
00003 
00004 #include "opennwa/Nwa.hpp"
00005 
00006 #include <iterator>
00007 #include <utility>
00008 
00009 namespace opennwa
00010 {
00011     namespace query
00012     {
00013       namespace details
00014       {
00015         /// Defines a generic predicate.
00016         ///
00017         /// Predicates take a transition and return true or false depending
00018         /// on whether the predicate holds for that transition or not.
00019         namespace predicates
00020         {
00021 
00022 #if 0
00023           template<typename Selector>
00024           struct SelectorTraits
00025           {
00026             typedef typename Selector::type type;
00027           };
00028 
00029           template<typename Object>
00030           struct SelectorTraits<Object*>
00031           {
00032             typedef
00033 #endif
00034 
00035           /// This class takes a selector and an object. It returns true for
00036           /// a transition if the selector returns that object.
00037           template<typename Selector>
00038           class SelectorEqualityPredicate
00039           {
00040           private:
00041             typedef typename Selector::type EqualityType;
00042 
00043             Selector selector;
00044             EqualityType mark;
00045 
00046           public:
00047             SelectorEqualityPredicate(Selector sel, EqualityType const & goal)
00048               : selector(sel)
00049               , mark(goal)
00050             {}
00051 
00052             template<typename T>
00053             bool operator() (T const & c) {
00054               return mark == selector(c);
00055             }
00056           };
00057 
00058 
00059           /// Like std::make_pair. Returns a SelectorEqualityPredicate of the
00060           /// appropriate type.
00061           template<typename Selector, typename EqualityType>
00062           SelectorEqualityPredicate<Selector>
00063           makeSelectorEqualityPredicate(Selector selector, EqualityType const & goal)
00064           {
00065             return SelectorEqualityPredicate<Selector>(selector, goal);
00066           }
00067         }
00068 
00069         
00070         /// This namespace defines filtering iterators.
00071         ///
00072         namespace filter
00073         {
00074 
00075           template<typename CPlusPlusIterator>
00076           class IteratorPairIterator
00077           {
00078           public:
00079             typedef std::forward_iterator_tag iterator_category;
00080             typedef typename std::iterator_traits<CPlusPlusIterator>::value_type value_type;
00081             typedef typename std::iterator_traits<CPlusPlusIterator>::pointer pointer;
00082             typedef typename std::iterator_traits<CPlusPlusIterator>::reference reference;
00083             typedef typename std::iterator_traits<CPlusPlusIterator>::difference_type difference_type;
00084 
00085             
00086           private:
00087             CPlusPlusIterator current;
00088             CPlusPlusIterator end;
00089 
00090           public:
00091             IteratorPairIterator(CPlusPlusIterator left, CPlusPlusIterator right)
00092               : current(left)
00093               , end(right)
00094             {}
00095 
00096             bool atEnd() {
00097               return current == end;
00098             }
00099 
00100             void operator++() {
00101               ++current;
00102             }
00103 
00104             bool operator==(IteratorPairIterator i) {
00105               return this->current == i->current;
00106             }
00107 
00108             value_type operator*() {
00109               return *current;
00110             }
00111           };
00112           
00113 
00114           template<typename BackingIterator, typename Predicate>
00115           class FilteringIterator
00116           {
00117           public:
00118             typedef std::forward_iterator_tag iterator_category;
00119             typedef typename std::iterator_traits<BackingIterator>::value_type value_type;
00120             typedef typename std::iterator_traits<BackingIterator>::pointer pointer;
00121             typedef typename std::iterator_traits<BackingIterator>::reference reference;
00122             typedef typename std::iterator_traits<BackingIterator>::difference_type difference_type;
00123             
00124             
00125           private:
00126             BackingIterator backing;
00127             Predicate predicate;
00128 
00129           public:
00130             FilteringIterator(BackingIterator start, Predicate pred)
00131               : backing(start)
00132               , predicate(pred)
00133             {
00134               if (!atEnd() && !predicate(*backing)) {
00135                 advance();
00136               }
00137             }
00138 
00139             void advance() {
00140               // Advance the backing iterator until either we reach the end
00141               // of that sequence, or the predicate no longer holds.
00142               do {
00143                 ++backing;
00144               } while (!backing.atEnd() && !predicate(*backing));
00145             }
00146 
00147             bool atEnd() {
00148               // We're at the end IFF our backing iterator is at the end
00149               return backing.atEnd();
00150             }
00151 
00152             void operator++() {
00153               advance();
00154             }
00155 
00156             bool operator==(FilteringIterator const & other) {
00157               return this->backing == other.backing;
00158             }
00159 
00160             value_type operator*() {
00161               return *backing;
00162             }
00163           };
00164           
00165 
00166       }
00167     }
00168   }
00169 }
00170 
00171 // Yo, Emacs!
00172 // Local Variables:
00173 //   c-file-style: "ellemtel"
00174 //   c-basic-offset: 2
00175 // End:
00176 
00177 #endif