00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef MORE_GEN_NARY_TREE_H
00031 #define MORE_GEN_NARY_TREE_H
00032
00033 #include <iterator>
00034 #include <stdexcept>
00035 #include <algorithm>
00036 #include <more/gen/memory.h>
00037 #include <more/gen/utility.h>
00038
00039
00040 namespace more {
00041 namespace gen {
00042
00043 using std::swap;
00044
00045
00046 namespace bits {
00047 struct _nary_tree_node_base : noncopyable
00048 {
00049 typedef _nary_tree_node_base self;
00050 _nary_tree_node_base()
00051 : m_prev(this), m_next(this), m_parent(0) {}
00052
00053 self* prev() { return m_prev; }
00054 self const* prev() const { return m_prev; }
00055 self* next() { return m_next; }
00056 self const* next() const { return m_next; }
00057
00058 void unlink()
00059 {
00060 m_prev->m_next = m_next;
00061 m_next->m_prev = m_prev;
00062 m_parent = 0;
00063 }
00064
00065 self* m_prev;
00066 self* m_next;
00067 self* m_parent;
00068 };
00069 }
00070
00071
00072 struct tree_iterator_tag : std::bidirectional_iterator_tag {};
00073
00074 template<typename T, typename Allocator> class nary_tree;
00075
00076
00077 namespace bits {
00078 template<typename T> class _nary_tree_node;
00079 template<typename T> class _nary_tree_iterator;
00080 template<typename T> class _const_nary_tree_iterator;
00081
00082 template<typename Node>
00083 struct _nary_tree_iterator
00084 {
00085 private:
00086 typedef _nary_tree_iterator self;
00087 public:
00088 typedef tree_iterator_tag iterator_category;
00089 typedef typename Node::value_type value_type;
00090 typedef ptrdiff_t difference_type;
00091 typedef typename Node::iterator iterator;
00092 typedef typename Node::const_iterator const_iterator;
00093 typedef value_type& reference;
00094 typedef value_type const& const_reference;
00095 typedef value_type* pointer;
00096
00097 _nary_tree_iterator() : m_cur(0) {}
00098 _nary_tree_iterator(_nary_tree_iterator const& it)
00099 : m_cur(it.m_cur) {}
00100 _nary_tree_iterator(_nary_tree_node_base* n) : m_cur(n) {}
00101 _nary_tree_iterator(_nary_tree_node_base const* n) : m_cur(n) {}
00102 _nary_tree_iterator& operator=(_nary_tree_iterator const& it)
00103 { m_cur = it.m_cur; return *this; }
00104
00105 bool operator==(_nary_tree_iterator const& it) const
00106 { return m_cur == it.m_cur; }
00107 bool operator!=(_nary_tree_iterator const& it) const
00108 { return m_cur != it.m_cur; }
00109
00110 _nary_tree_iterator& operator++()
00111 { m_cur = m_cur->next(); return *this; }
00112 _nary_tree_iterator operator++(int)
00113 { _nary_tree_iterator tmp = *this; ++*this; return tmp; }
00114 _nary_tree_iterator& operator--()
00115 { m_cur = m_cur->prev(); return *this; }
00116 _nary_tree_iterator operator--(int)
00117 { _nary_tree_iterator tmp = *this; --*this; return tmp; }
00118
00119 self begin() { return static_cast<Node*>(m_cur)->begin(); }
00120 self end() { return static_cast<Node*>(m_cur)->end(); }
00121 bool empty() { return begin() == end(); }
00122
00123 self parent()
00124 {
00125 if (!m_cur->m_parent)
00126 throw std::logic_error("_nary_tree_iterator::parent(): "
00127 "Root node has no parent.");
00128 return static_cast<Node*>(m_cur)->parent();
00129 }
00130
00131 reference operator*() { return static_cast<Node*>(m_cur)->value; }
00132 pointer operator->() { return &static_cast<Node*>(m_cur)->value; }
00133
00134 private:
00135 _nary_tree_node_base* m_cur;
00136
00137 friend class _nary_tree_node<value_type>;
00138 template<typename U, typename Allocator> friend class nary_tree;
00139 friend class _const_nary_tree_iterator<Node>;
00140 };
00141
00142 template<typename Node>
00143 struct _const_nary_tree_iterator
00144 {
00145 typedef _const_nary_tree_iterator self;
00146 typedef tree_iterator_tag iterator_category;
00147 typedef const typename Node::value_type value_type;
00148 typedef ptrdiff_t difference_type;
00149 typedef typename Node::iterator iterator;
00150 typedef typename Node::const_iterator const_iterator;
00151 typedef value_type& reference;
00152 typedef value_type const& const_reference;
00153 typedef value_type* pointer;
00154
00155 _const_nary_tree_iterator() : m_cur(0) {}
00156 _const_nary_tree_iterator(_const_nary_tree_iterator const& it)
00157 : m_cur(it.m_cur) {}
00158 _const_nary_tree_iterator(_nary_tree_iterator<Node> const& it)
00159 : m_cur(it.m_cur) {}
00160 _const_nary_tree_iterator(_nary_tree_node_base* n)
00161 : m_cur(n) {}
00162 _const_nary_tree_iterator(_nary_tree_node_base const* n)
00163 : m_cur(const_cast<_nary_tree_node_base*>(n)) {}
00164 _const_nary_tree_iterator&
00165 operator=(_const_nary_tree_iterator const& it)
00166 { m_cur = it.m_cur; return *this; }
00167
00168 bool operator==(_const_nary_tree_iterator const& it) const
00169 { return m_cur == it.m_cur; }
00170 bool operator!=(_const_nary_tree_iterator const& it) const
00171 { return m_cur != it.m_cur; }
00172
00173 _const_nary_tree_iterator& operator++()
00174 { m_cur = m_cur->next(); return *this; }
00175 _const_nary_tree_iterator operator++(int)
00176 { _const_nary_tree_iterator tmp = *this; ++*this; return tmp; }
00177 _const_nary_tree_iterator& operator--()
00178 { m_cur = m_cur->prev(); return *this; }
00179 _const_nary_tree_iterator operator--(int)
00180 { _const_nary_tree_iterator tmp = *this; --*this; return tmp; }
00181
00182 self begin() { return static_cast<Node*>(m_cur)->begin(); }
00183 self end() { return static_cast<Node*>(m_cur)->end(); }
00184 bool empty() { return begin() == end(); }
00185
00186 self parent()
00187 {
00188 if (!m_cur->m_parent)
00189 throw std::logic_error("_const_nary_tree_iterator::parent(): "
00190 "Root node has no parent.");
00191 return static_cast<Node*>(m_cur)->parent();
00192 }
00193
00194 reference operator*() { return static_cast<Node*>(m_cur)->value; }
00195 pointer operator->() { return &static_cast<Node*>(m_cur)->value; }
00196
00197 private:
00198 _nary_tree_node_base* m_cur;
00199
00200 friend class _nary_tree_node<value_type>;
00201 template<typename U, typename Allocator> friend class nary_tree;
00202 };
00203
00204 template<typename T>
00205 struct _nary_tree_node
00206 : protected _nary_tree_node_base
00207 {
00208 typedef _nary_tree_node self;
00209 typedef _nary_tree_node_base node_base;
00210 typedef _nary_tree_iterator<self> iterator;
00211 typedef _const_nary_tree_iterator<self> const_iterator;
00212 typedef T value_type;
00213 typedef T& reference;
00214 typedef T const& const_reference;
00215 typedef T* pointer;
00216 typedef ptrdiff_t difference_type;
00217 typedef size_t size_type;
00218
00219 _nary_tree_node() { m_inf_child.m_parent = this; }
00220 _nary_tree_node(const_reference x)
00221 : value(x) { m_inf_child.m_parent = this;}
00222 ~_nary_tree_node() { unlink(); }
00223
00224 self* parent() { return static_cast<self*>(m_parent); }
00225 self const* parent() const {
00226 return static_cast<self const*>(m_parent);
00227 }
00228
00229 iterator begin() { return inf_child()->next(); }
00230 iterator end() { return inf_child(); }
00231 const_iterator begin() const { return inf_child()->next(); }
00232 const_iterator end() const { return inf_child(); }
00233
00234 iterator insert(iterator it_pos, _nary_tree_node* v);
00235 _nary_tree_node* erase(iterator it_pos);
00236
00237 private:
00238 node_base* inf_child() { return &m_inf_child; }
00239 node_base const* inf_child() const { return &m_inf_child; }
00240
00241 _nary_tree_node_base m_inf_child;
00242 value_type value;
00243
00244 friend class iterator;
00245 friend class const_iterator;
00246 template<typename U, typename Allocator> friend class nary_tree;
00247 };
00248 }
00249
00250
00251
00252
00253
00254
00255 template< typename T, typename Allocator = gen::allocator<T> >
00256 struct nary_tree
00257 {
00258 typedef Allocator allocator_type;
00259 typedef bits::_nary_tree_node<T> node_type;
00260 private:
00261 typedef typename allocator_type::rebind<node_type>::other
00262 real_allocator_type;
00263 public:
00264 typedef typename node_type::iterator iterator;
00265 typedef typename node_type::const_iterator const_iterator;
00266 typedef typename node_type::pointer pointer;
00267 typedef typename node_type::reference reference;
00268 typedef typename node_type::const_reference const_reference;
00269 typedef typename node_type::size_type size_type;
00270 typedef typename node_type::difference_type difference_type;
00271
00272 nary_tree()
00273 : m_root(m_alloc.allocate(1))
00274 {
00275 m_alloc.construct(m_root);
00276 }
00277
00278 nary_tree(nary_tree const& tr)
00279 : m_root(m_alloc.allocate(1))
00280 {
00281 m_alloc.construct(m_root);
00282 copy_node(tr.m_root, m_root);
00283 }
00284
00285 ~nary_tree()
00286 {
00287 clear();
00288 m_alloc.destroy(m_root);
00289 m_alloc.deallocate(m_root, 1);
00290 }
00291
00292 nary_tree&
00293 operator=(nary_tree const& tr)
00294 {
00295 clear();
00296 copy_node(tr.m_root, m_root);
00297 return *this;
00298 }
00299
00300 struct swapper
00301 {
00302 swapper()
00303 : m_root(m_alloc.allocate(1))
00304 {
00305 m_alloc.construct(m_root);
00306 }
00307 swapper(nary_tree& t)
00308 : m_root(m_alloc.allocate(1))
00309 {
00310 m_alloc.construct(m_root);
00311 std::swap(m_root, t.m_root);
00312 }
00313 swapper(swapper& sw)
00314 : m_root(m_alloc.allocate(1))
00315 {
00316 m_alloc.construct(m_root);
00317 std::swap(m_root, sw.m_root);
00318 }
00319 swapper& operator=(nary_tree& t)
00320 {
00321 std::swap(m_root, t.m_root);
00322 return *this;
00323 }
00324 swapper& operator=(swapper& sw)
00325 {
00326 std::swap(m_root, sw.m_root);
00327 return *this;
00328 }
00329 ~swapper()
00330 {
00331 nary_tree t(*this);
00332 m_alloc.destroy(m_root);
00333 m_alloc.deallocate(m_root, 1);
00334 }
00335
00336 private:
00337 swapper(swapper const&) {}
00338 swapper& operator=(swapper const&) {}
00339
00340 node_type* m_root;
00341 real_allocator_type m_alloc;
00342 friend class nary_tree;
00343 };
00344
00345 nary_tree(swapper& sw)
00346 : m_root(m_alloc.allocate(1))
00347 {
00348 m_alloc.construct(m_root);
00349 std::swap(m_root, sw.m_root);
00350 }
00351
00352 nary_tree& operator=(swapper& sw)
00353 {
00354 std::swap(m_root, sw.m_root);
00355 return *this;
00356 }
00357
00358 void set_root(const_reference x)
00359 {
00360 m_root->value = x;
00361 }
00362
00363 iterator root() { return iterator(m_root); }
00364 const_iterator root() const { return const_iterator(m_root); }
00365
00366 iterator insert(iterator it_pos, const_reference v)
00367 {
00368 node_type* n_new = m_alloc.allocate(1);
00369 m_alloc.construct(n_new);
00370 n_new->value = v;
00371 return static_cast<node_type*>(it_pos.m_cur->m_parent)
00372 ->insert(it_pos, n_new);
00373 }
00374
00375 iterator erase(iterator it_pos)
00376 {
00377 node_type* n_old = static_cast<node_type*>(it_pos.m_cur);
00378 erase(n_old->begin(), n_old->end());
00379 node_type* n_next = static_cast<node_type*>(n_old->m_next);
00380 m_alloc.destroy(n_old);
00381 m_alloc.deallocate(n_old, 1);
00382 return iterator(n_next);
00383 }
00384
00385 void erase(iterator first, iterator last)
00386 {
00387 while (first != last)
00388 first = erase(first);
00389 }
00390
00391 void clear() { erase(m_root->begin(), m_root->end()); }
00392
00393 void swap(nary_tree& x)
00394 {
00395 std::swap(m_root, x.m_root);
00396 }
00397
00398 private:
00399 void copy_node(node_type const* src, node_type* dst);
00400
00401 real_allocator_type m_alloc;
00402 node_type* m_root;
00403 };
00404
00405 template<typename TreeIterator0, typename TreeIterator1>
00406 bool
00407 subtree_counted_equal(TreeIterator0 it0, TreeIterator0 it0end,
00408 TreeIterator1 it1, TreeIterator1 it1end)
00409 {
00410 for (;;) {
00411 if (it0 == it0end)
00412 return it1 == it1end;
00413 if (it1 == it1end)
00414 return false;
00415 if (*it0 != *it1)
00416 return false;
00417 if (!subtree_counted_equal(it0.begin(), it0.end(),
00418 it1.begin(), it1.end()))
00419 return false;
00420 ++it0;
00421 ++it1;
00422 }
00423 }
00424
00425 template<typename T0, typename T1>
00426 bool
00427 operator==(nary_tree<T0> const& t0, nary_tree<T1> const& t1)
00428 {
00429 return *t0.root() == *t1.root()
00430 && subtree_counted_equal(t0.root().begin(), t0.root().end(),
00431 t1.root().begin(), t1.root().end());
00432 }
00433
00434 template<typename T, typename Allocator>
00435 inline void
00436 nary_tree<T, Allocator>::copy_node(node_type const* src, node_type* dst)
00437 {
00438 dst->value = src->value;
00439 for (typename node_type::const_iterator it = src->begin();
00440 it != src->end(); ++it) {
00441 node_type* nd = m_alloc.allocate(1);
00442 m_alloc.construct(nd);
00443 copy_node(static_cast<node_type const*>(it.m_cur), nd);
00444 dst->insert(dst->end(), nd);
00445 }
00446 }
00447
00448 template<typename T, typename Allocator>
00449 inline void
00450 swap(nary_tree<T, Allocator>& x, nary_tree<T, Allocator>& y)
00451 {
00452 x.swap(y);
00453 }
00454
00455 template<typename TreeIterator>
00456 void
00457 subtree_dump(TreeIterator it, std::ostream& os,
00458 int level = 0, unsigned int cont = 0)
00459 {
00460 if (level) {
00461 for (int i = 0; i < level; ++i)
00462 os << (cont & (1<<i)? "| " : " ");
00463 os << "|\n";
00464 }
00465 for (int i = 0; i < level; ++i)
00466 os << (cont & (1<<i)? "| " : " ");
00467 os << (level? '+' : '-')
00468 << (it.empty()? "----" : "--+-") << *it << '\n';
00469 cont |= 2<<level;
00470 for (TreeIterator it_sub = it.begin(); it_sub != it.end(); ++it_sub) {
00471 if (it_sub == --it.end())
00472 cont &= ~(2<<level);
00473 subtree_dump(it_sub, os, level+1, cont);
00474 }
00475 }
00476
00477
00478 namespace bits {
00479 template<typename T>
00480 typename _nary_tree_node<T>::iterator
00481 _nary_tree_node<T>::insert(iterator it_pos, _nary_tree_node* n_new)
00482 {
00483 node_base* n_pos = it_pos.m_cur;
00484 n_new->m_next = n_pos;
00485 n_new->m_prev = n_pos->m_prev;
00486 n_pos->m_prev = n_new;
00487 n_new->m_prev->m_next = n_new;
00488 n_new->m_parent = this;
00489 return iterator(n_new);
00490 }
00491
00492 template<typename T>
00493 _nary_tree_node<T>*
00494 _nary_tree_node<T>::erase(iterator it_pos)
00495 {
00496 self* n_pos = static_cast<self*>(it_pos.m_cur);
00497 node_base* n_next = n_pos->m_next;
00498 n_pos->m_prev->m_next = n_next;
00499 n_next->m_prev = n_pos->m_prev;
00500 return n_pos;
00501 }
00502 }
00503
00504
00505 }}
00506
00507 #endif