00001 #ifndef s11n_util_NODE_UTIL_HPP_INCLUDED
00002 #define s11n_util_NODE_UTIL_HPP_INCLUDED 1
00003
00004 #include <map>
00005 #include <list>
00006 #include <s11n.net/s11n/traits.hpp>
00007
00008 namespace s11n {
00009
00010
00011
00012
00013
00014 namespace util {
00015
00016
00017
00018
00019
00020
00021
00022
00023 template <typename NodeT>
00024 class node_tree
00025 {
00026 public:
00027 typedef NodeT node_type;
00028 typedef ::s11n::node_traits< node_type > traits_type;
00029
00030
00031
00032
00033
00034
00035
00036
00037 explicit node_tree( node_type * root ) : m_root(root), m_count(0)
00038 {
00039 this->climb_tree( root );
00040 }
00041
00042 node_tree() : m_root(0), m_count(0)
00043 {}
00044
00045 ~node_tree() {}
00046
00047
00048 typedef typename traits_type::child_list_type list_type;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 size_t climb_tree( node_type * node, size_t internal_use = 0 )
00068 {
00069 if( 0 == internal_use )
00070 {
00071 this->m_count = 0;
00072 this->m_root = node;
00073 this->m_rmap.clear();
00074 if( node ) this->m_rmap[node] = 0;
00075 }
00076 if( ! node ) return 0;
00077
00078 ++this->m_count;
00079 list_type & chlist = traits_type::children(*node);
00080 typename list_type::iterator it = chlist.begin(),
00081 et = chlist.end();
00082 for( ; et != it; ++it )
00083 {
00084 this->m_rmap[(*it)] = node;
00085 this->climb_tree( (*it), 1 + internal_use );
00086 }
00087 return this->m_count;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 node_type * parent_of( node_type & node )
00100 {
00101 typename reverse_map_type::iterator it = this->m_rmap.find( &node );
00102 if( it == this->m_rmap.end() ) return 0;
00103 return (*it).second;
00104 }
00105
00106
00107
00108
00109
00110 list_type & children_of( node_type & node )
00111 {
00112 return traits_type::children(node);
00113 }
00114
00115
00116
00117
00118
00119
00120 bool take_node( node_type * node )
00121 {
00122 typename reverse_map_type::iterator rit = this->m_rmap.find( node );
00123 if( rit == this->m_rmap.end() ) return false;
00124 node_type * p = (*rit).second;
00125 if( p )
00126 {
00127
00128 typename list_type::iterator it = traits_type::children(*p).begin(),
00129 et = traits_type::children(*p).end();
00130 for( ; et != it; ++it )
00131 {
00132 if( (*it) == node )
00133 {
00134 traits_type::children(*p).erase( it );
00135 break;
00136 }
00137 }
00138 }
00139
00140 this->m_rmap.erase(rit);
00141 if( node == this->root() )
00142 {
00143 this->m_root = 0;
00144 }
00145 return true;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 bool reparent( node_type * n, node_type * newp )
00168 {
00169 if( (!n) || (!newp) || (!this->root()) || (this->root() == n) )
00170 {
00171 return false;
00172 }
00173 if( ! this->take_child( n ) )
00174 {
00175 return false;
00176 }
00177 traits_type::children(*newp).push_back( n );
00178 this->m_rmap[n] = newp;
00179 traits_type::children(*newp).push_back( n );
00180 return true;
00181 }
00182
00183
00184
00185
00186
00187 node_type * root() { return this->m_root; }
00188
00189
00190
00191
00192
00193
00194 void clear()
00195 {
00196 this->m_rmap.clear();
00197 this->m_root = 0;
00198 }
00199
00200 private:
00201 typedef std::map< node_type *, node_type * > reverse_map_type;
00202 reverse_map_type m_rmap;
00203 node_type * m_root;
00204 size_t m_count;
00205 };
00206
00207 } }
00208
00209
00210 #endif // s11n_util_NODE_UTIL_HPP_INCLUDED