Inferno
0.2
|
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