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