Inferno  0.2
walk.hpp
Go to the documentation of this file.
00001 #ifndef WALK_HPP
00002 #define WALK_HPP
00003 
00004 #include "node/node.hpp"
00005 #include "transformation.hpp"
00006 
00007 /// Iterator for FlattenNode
00008 class FlattenNode_iterator : public ContainerInterface::iterator_interface
00009 {
00010 public:
00011   // Standard types for stl compliance (note that the iterators are implicitly const)
00012     typedef forward_iterator_tag iterator_category;
00013     typedef TreePtrInterface value_type;
00014     typedef int difference_type;
00015     typedef const value_type *pointer;
00016     typedef const value_type &reference;
00017 
00018   // Copy constructor and standard iterator operations
00019   FlattenNode_iterator( const FlattenNode_iterator & other );
00020   virtual shared_ptr<ContainerInterface::iterator_interface> Clone() const;
00021   virtual FlattenNode_iterator &operator++();
00022   virtual reference operator*() const;
00023   virtual pointer operator->() const;
00024   virtual bool operator==( const ContainerInterface::iterator_interface &ib ) const;
00025   virtual bool operator!=( const ContainerInterface::iterator_interface &ib ) const { return !operator==(ib); }
00026   virtual void Overwrite( pointer v ) const;
00027     virtual const bool IsOrdered() const;
00028     // Some additional operations specific to walk iterators
00029     operator string() const;
00030     FlattenNode_iterator(); // makes "end" iterator
00031     FlattenNode_iterator( TreePtr<Node> root );
00032 private:
00033     bool IsAtEnd() const;
00034     void BypassEndOfContainer();
00035     void NormaliseNewMember();
00036     inline Itemiser::Element *GetCurrentMember() const
00037     {
00038       ASSERT( mit != m_end );
00039       return root->ItemiseIndex( mit );
00040     }
00041 
00042     int mit;
00043     int m_end;
00044     ContainerInterface::iterator cit;
00045     ContainerInterface::iterator c_end;
00046     TreePtr<Node> root;
00047     bool empty; // TODO use NULL root for empty
00048 };
00049 
00050 /*! Stated out traversal across a node's children. UniqueWalks the members and elements of containers
00051     but does not follow any TreePtr. Basically an itemise that expands containers. */
00052 typedef ContainerFromIterator< FlattenNode_iterator, TreePtr<Node> > FlattenNode;
00053 
00054 
00055 /// Iterator for Walk
00056 class Walk_iterator : public ContainerInterface::iterator_interface
00057 {
00058 public:
00059   // Standard types for stl compliance (note that the iterators are implicitly const)
00060     typedef forward_iterator_tag iterator_category;
00061   typedef TreePtrInterface value_type;
00062   typedef int difference_type;
00063   typedef const value_type *pointer;
00064   typedef const value_type &reference;
00065 
00066   // Copy constructor and standard iterator operations
00067   Walk_iterator( const Walk_iterator & other );
00068   virtual shared_ptr<ContainerInterface::iterator_interface> Clone() const;
00069   virtual Walk_iterator &operator++();
00070   virtual reference operator*() const;
00071   virtual pointer operator->() const;
00072   virtual bool operator==( const ContainerInterface::iterator_interface &ib ) const;
00073   virtual bool operator!=( const ContainerInterface::iterator_interface &ib ) const { return !operator==(ib); }
00074   virtual void Overwrite( pointer v ) const;
00075     virtual const bool IsOrdered() const;
00076     // Some additional operations specific to walk iterators
00077     operator string() const;
00078     virtual void AdvanceOver();
00079     virtual void AdvanceInto();
00080     Walk_iterator(); // makes "end" iterator
00081     Walk_iterator( TreePtr<Node> &root,
00082                      Filter *out_filter = NULL,
00083                  Filter *recurse_filter = NULL );
00084 protected:
00085     virtual void DoNodeFilter();
00086     bool IsAtEndOfChildren() const;
00087     void BypassEndOfChildren();
00088     virtual shared_ptr<ContainerInterface> GetChildContainer( TreePtr<Node> n ) const;
00089     void Push( TreePtr<Node> n );
00090 
00091     shared_ptr< TreePtr<Node> > root;
00092     Filter *out_filter;
00093     Filter *recurse_filter;
00094     struct StateEntry
00095     {
00096         shared_ptr<ContainerInterface> container;
00097         ContainerInterface::iterator iterator;
00098     };
00099     stack< StateEntry > state;
00100     bool done;   
00101 };
00102 
00103 
00104 /*! Inferno's tree-walking class. This is a stated out depth-first tree walker.
00105     A walk object is constructed on a node (possibly with other params) and it acts
00106     like an OOStd container whose iterator walks the subtree with sucessive invocations
00107     of operator++. A walking loop may be created using FOREACH as with containers. */
00108 typedef ContainerFromIterator< Walk_iterator, TreePtr<Node>, Filter *, Filter * > Walk;
00109 
00110 
00111 /// Filter that only matches each Node one time, then not again until Reset() is called
00112 struct UniqueFilter : public Filter
00113 {
00114     virtual bool IsMatch( TreePtr<Node> context,
00115                           TreePtr<Node> root );
00116     void Reset() { seen.clear(); }                         
00117     Set< TreePtr<Node> > seen;    
00118 };
00119 
00120 
00121 /// Iterator for ParentWalk
00122 class ParentWalk_iterator : public Walk::iterator
00123 {
00124 public:
00125     ParentWalk_iterator(); // makes "end" iterator
00126     ~ParentWalk_iterator(); 
00127     ParentWalk_iterator( const ParentWalk_iterator &other );
00128     ParentWalk_iterator &operator=( const ParentWalk_iterator &other );
00129     ParentWalk_iterator( TreePtr<Node> &root );
00130   virtual shared_ptr<ContainerInterface::iterator_interface> Clone() const;    
00131 protected:
00132     UniqueFilter *unique_filter;
00133 };
00134 
00135 /*! Version of Walk that only sees a node once for each parent i.e. 
00136     with a->c, b->c, c->d
00137     we get c twice but d only once (Walk would get d twice too) */
00138 typedef ContainerFromIterator< ParentWalk_iterator, TreePtr<Node> > ParentWalk;
00139 
00140 
00141 /// Iterator for UniqueWalk
00142 class UniqueWalk_iterator : public Walk::iterator
00143 {
00144 public:
00145     UniqueWalk_iterator(); // makes "end" iterator
00146     ~UniqueWalk_iterator(); 
00147     UniqueWalk_iterator( const UniqueWalk_iterator &other );        
00148     UniqueWalk_iterator &operator=( const UniqueWalk_iterator &other );
00149     UniqueWalk_iterator( TreePtr<Node> &root );
00150   virtual shared_ptr<ContainerInterface::iterator_interface> Clone() const;    
00151 protected:
00152     UniqueFilter *unique_filter;
00153 };
00154 
00155 /*! UniqueWalk presents each element exactly once, and skips NULL pointers */
00156 typedef ContainerFromIterator< UniqueWalk_iterator, TreePtr<Node> > UniqueWalk;
00157 
00158 #endif
00159