00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ADOBE_FOREST_HPP
00010 #define ADOBE_FOREST_HPP
00011
00012
00013
00014 #include <adobe/config.hpp>
00015
00016 #include <adobe/algorithm/reverse.hpp>
00017 #include <adobe/iterator/set_next.hpp>
00018
00019 #include <boost/iterator/iterator_facade.hpp>
00020 #include <boost/next_prior.hpp>
00021 #include <boost/range.hpp>
00022
00023 #include <cstddef>
00024 #include <iterator>
00025 #include <functional>
00026
00027
00028
00029 namespace adobe {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 enum
00040 {
00041 forest_trailing_edge,
00042 forest_leading_edge
00043 };
00044
00045
00046
00047 template <typename I>
00048 inline void pivot(I& i) { i.edge() ^= 1; }
00049
00050 template <typename I>
00051 inline I pivot_of(I i) { pivot(i); return i; }
00052
00053
00054
00055 template <typename I>
00056 inline I leading_of(I i) { i.edge() = forest_leading_edge; return i; }
00057
00058 template <typename I>
00059 inline I trailing_of(I i) { i.edge() = forest_trailing_edge; return i; }
00060
00061
00062
00063 template <typename I>
00064 I find_parent(I i)
00065 {
00066 do { i = trailing_of(i); ++i; } while (i.edge() != forest_trailing_edge);
00067 return i;
00068 }
00069
00070
00071
00072 template <typename I>
00073 bool has_children(const I& i)
00074 { return !i.equal_node(boost::next(leading_of(i))); }
00075
00076
00077
00078 template <typename I>
00079 class child_iterator : public boost::iterator_adaptor<child_iterator<I>, I>
00080 {
00081 public:
00082 child_iterator() { }
00083 explicit child_iterator(I x) : child_iterator::iterator_adaptor_(x) { }
00084 template <typename U> child_iterator(const child_iterator<U>& u) :
00085 child_iterator::iterator_adaptor_(u.base()) { }
00086
00087 private:
00088 friend class boost::iterator_core_access;
00089
00090 void increment() { pivot(this->base_reference()); ++this->base_reference(); }
00091 void decrement() { --this->base_reference(); pivot(this->base_reference()); }
00092 };
00093
00094
00095
00096 template <typename I>
00097 I find_edge(I x, std::size_t edge) { while (x.edge() != edge) ++x; return x; }
00098
00099 template <typename I>
00100 I find_edge_reverse(I x, std::size_t edge) { while (x.edge() != edge) --x; return x; }
00101
00102
00103
00104 template <typename I, std::size_t Edge>
00105 class edge_iterator : public boost::iterator_adaptor<edge_iterator<I, Edge>, I>
00106 {
00107 public:
00108 edge_iterator() { }
00109 explicit edge_iterator(I x) : edge_iterator::iterator_adaptor_(find_edge(x, Edge))
00110 { }
00111 template <typename U> edge_iterator(const edge_iterator<U, Edge>& u) :
00112 edge_iterator::iterator_adaptor_(u.base()) { }
00113
00114 private:
00115 friend class boost::iterator_core_access;
00116
00117 void increment()
00118 { this->base_reference() = find_edge(boost::next(this->base()), Edge); }
00119
00120 void decrement()
00121 { this->base_reference() = find_edge_reverse(boost::prior(this->base()), Edge); }
00122 };
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 template < typename I,
00134 typename P>
00135 class filter_fullorder_iterator
00136 : public boost::iterator_adaptor<filter_fullorder_iterator<I, P>, I>
00137 {
00138 public:
00139 filter_fullorder_iterator() { }
00140
00141 filter_fullorder_iterator(I f, I l, P p) :
00142 filter_fullorder_iterator::iterator_adaptor_(skip_forward(f, l, p)),
00143 inside_m(true),
00144 first_m(f),
00145 last_m(l),
00146 predicate_m(p)
00147 { }
00148
00149 filter_fullorder_iterator(I f, I l) :
00150 filter_fullorder_iterator::iterator_adaptor_(skip_forward(f, l, P())),
00151 inside_m(true),
00152 first_m(f),
00153 last_m(l)
00154 { }
00155
00156 template <typename U> filter_fullorder_iterator(const filter_fullorder_iterator<U, P>& x) :
00157 filter_fullorder_iterator::iterator_adaptor_(x.base()),
00158 inside_m(x.inside_m),
00159 first_m(x.first_m),
00160 last_m(x.last_m),
00161 predicate_m(x.predicate_m)
00162 { }
00163
00164 P predicate() const { return predicate_m; }
00165
00166 std::size_t edge() const { return this->base().edge(); }
00167 std::size_t& edge() { return this->base_reference().edge(); }
00168
00169 bool equal_node(const filter_fullorder_iterator& y) const { return this->base().equal_node(y.base()); }
00170
00171 private:
00172 friend class boost::iterator_core_access;
00173
00174 void increment()
00175 {
00176 I i = this->base();
00177
00178 if (i == last_m) inside_m = false;
00179 ++i;
00180 if (i == first_m) inside_m = true;
00181 if (inside_m) i = skip_forward(i, last_m, predicate_m);
00182 this->base_reference() = i;
00183 }
00184
00185 static I skip_forward(I f, I l, P p)
00186
00187 {
00188 while((f.edge() == forest_leading_edge) && (f != l) && !p(*f)) {
00189 f.edge() = forest_trailing_edge;
00190 ++f;
00191 }
00192 return f;
00193 }
00194
00195 static I skip_backward(I f, I l, P p)
00196
00197 {
00198 while((l.edge() == forest_trailing_edge) && (f != l) && !p(*l)) {
00199 l.edge() = forest_leading_edge;
00200 --l;
00201 }
00202 return l;
00203 }
00204
00205 void decrement()
00206 {
00207 I i = this->base();
00208
00209 if (i == first_m) inside_m = false;
00210 --i;
00211 if (i == last_m) inside_m = true;
00212 if (inside_m) i = skip_backward(first_m, i, predicate_m);
00213 this->base_reference() = i;
00214 }
00215
00216 bool inside_m;
00217 I first_m;
00218 I last_m;
00219 P predicate_m;
00220 };
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 template <typename I>
00237 class reverse_fullorder_iterator : public boost::iterator_facade<reverse_fullorder_iterator<I>,
00238 typename boost::iterator_value<I>::type, std::bidirectional_iterator_tag,
00239 typename boost::iterator_reference<I>::type>
00240 {
00241 typedef typename boost::iterator_facade<reverse_fullorder_iterator<I>,
00242 typename boost::iterator_value<I>::type, std::bidirectional_iterator_tag,
00243 typename boost::iterator_reference<I>::type>
00244 inherited_t;
00245 public:
00246 typedef I iterator_type;
00247 typedef typename inherited_t::reference reference;
00248
00249 reverse_fullorder_iterator() : edge_m(forest_trailing_edge) { }
00250 reverse_fullorder_iterator(I x) : base_m(--x), edge_m(forest_leading_edge - base_m.edge())
00251 { }
00252 template <typename U> reverse_fullorder_iterator(const reverse_fullorder_iterator<U>& x) :
00253 base_m(x.base()), edge_m(x.edge_m)
00254 { }
00255
00256 iterator_type base() const { return boost::next(base_m); }
00257
00258 std::size_t edge() const { return edge_m; }
00259 std::size_t& edge() { return edge_m; }
00260
00261 bool equal_node(const reverse_fullorder_iterator& y) const
00262 { return base_m.equal_node(y.base_m); }
00263
00264 private:
00265 friend class boost::iterator_core_access;
00266
00267 void increment()
00268 {
00269 base_m.edge() = forest_leading_edge - edge_m;
00270 --base_m;
00271 edge_m = forest_leading_edge - base_m.edge();
00272 }
00273 void decrement()
00274 {
00275 base_m.edge() = forest_leading_edge - edge_m;
00276 ++base_m;
00277 edge_m = forest_leading_edge - base_m.edge();
00278 }
00279 reference dereference() const { return *base_m; }
00280
00281 bool equal(const reverse_fullorder_iterator& y) const
00282 { return (base_m == y.base_m) && (edge_m == y.edge_m); }
00283
00284 I base_m;
00285 std::size_t edge_m;
00286 };
00287
00288
00289
00290 template <typename I>
00291 class depth_fullorder_iterator : public boost::iterator_adaptor<depth_fullorder_iterator<I>, I>
00292 {
00293 public:
00294 typedef typename boost::iterator_adaptor<depth_fullorder_iterator<I>, I>::difference_type difference_type;
00295
00296 depth_fullorder_iterator(difference_type d = 0) : depth_m(d) { }
00297 explicit depth_fullorder_iterator(I x, difference_type d = 0) :
00298 depth_fullorder_iterator::iterator_adaptor_(x),
00299 depth_m(d)
00300 { }
00301 template <typename U> depth_fullorder_iterator(const depth_fullorder_iterator<U>& x) :
00302 depth_fullorder_iterator::iterator_adaptor_(x.base()),
00303 depth_m(x.depth_m)
00304 { }
00305
00306 difference_type depth() const { return depth_m; }
00307 std::size_t edge() const { return this->base().edge(); }
00308 std::size_t& edge() { return this->base_reference().edge(); }
00309 bool equal_node(depth_fullorder_iterator const& y) const { return this->base().equal_node(y.base()); }
00310
00311 private:
00312 friend class boost::iterator_core_access;
00313
00314 void increment()
00315 {
00316 std::size_t old_edge(edge());
00317 ++this->base_reference();
00318 if (old_edge == edge()) depth_m += difference_type(old_edge << 1) - 1;
00319 }
00320 void decrement()
00321 {
00322 bool old_edge(edge());
00323 --this->base_reference();
00324 if (old_edge == edge()) depth_m -= difference_type(old_edge << 1) - 1;
00325 }
00326
00327 difference_type depth_m;
00328 };
00329
00330
00331
00332 template <typename Forest> class child_adaptor;
00333 template <typename T> class forest;
00334 template <typename T> void swap(forest<T>&, forest<T>&);
00335
00336
00337
00338 #if !defined(ADOBE_NO_DOCUMENTATION)
00339 namespace implementation {
00340
00341 template <typename D>
00342 struct node_base
00343 {
00344 enum next_prior_t
00345 {
00346 prior_s,
00347 next_s
00348 };
00349
00350 typedef D* node_ptr;
00351 typedef node_ptr& reference;
00352
00353 node_base()
00354 {
00355
00356 nodes_m[forest_leading_edge][std::size_t(next_s)] = static_cast<node_ptr>(this);
00357 nodes_m[forest_trailing_edge][std::size_t(prior_s)] = static_cast<node_ptr>(this);
00358 }
00359
00360 node_ptr& link(std::size_t edge, next_prior_t link)
00361 { return nodes_m[edge][std::size_t(link)]; }
00362
00363 node_ptr link(std::size_t edge, next_prior_t link) const
00364 { return nodes_m[edge][std::size_t(link)]; }
00365
00366 node_ptr nodes_m[2][2];
00367 };
00368
00369 template <typename T>
00370 struct node : public node_base<node<T> >
00371 {
00372 typedef T value_type;
00373
00374 explicit node(const value_type& data) : data_m(data) { }
00375
00376 value_type data_m;
00377 };
00378
00379
00380
00381 template <typename T> class forest_const_iterator;
00382
00383 template <typename T>
00384 class forest_iterator : public boost::iterator_facade<forest_iterator<T>,
00385 T,
00386 std::bidirectional_iterator_tag>
00387 {
00388 typedef boost::iterator_facade<forest_iterator<T>,
00389 T,
00390 std::bidirectional_iterator_tag> inherited_t;
00391 public:
00392 typedef typename inherited_t::reference reference;
00393 typedef typename inherited_t::difference_type difference_type;
00394 typedef typename inherited_t::value_type value_type;
00395
00396 forest_iterator() :
00397 node_m(0), edge_m(forest_leading_edge) { }
00398
00399 forest_iterator(const forest_iterator& x) :
00400 node_m(x.node_m), edge_m(x.edge_m) { }
00401
00402 std::size_t edge() const { return edge_m; }
00403 std::size_t& edge() { return edge_m; }
00404 bool equal_node(forest_iterator const& y) const { return node_m == y.node_m; }
00405
00406 private:
00407 friend class adobe::forest<value_type>;
00408 friend class boost::iterator_core_access;
00409 template <typename> friend class forest_iterator;
00410 template <typename> friend class forest_const_iterator;
00411 friend struct unsafe::set_next_fn<forest_iterator>;
00412
00413 typedef node<T> node_t;
00414
00415 reference dereference() const { return node_m->data_m; }
00416
00417 void increment()
00418 {
00419 node_t* next(node_m->link(edge_m, node_t::next_s));
00420
00421 if (edge_m) edge_m = std::size_t(next != node_m);
00422 else edge_m = std::size_t(next->link(forest_leading_edge, node_t::prior_s) == node_m);
00423
00424 node_m = next;
00425 }
00426
00427 void decrement()
00428 {
00429 node_t* next(node_m->link(edge_m, node_t::prior_s));
00430
00431 if (edge_m) edge_m = std::size_t(next->link(forest_trailing_edge, node_t::next_s) != node_m);
00432 else edge_m = std::size_t(next == node_m);
00433
00434 node_m = next;
00435 }
00436
00437 bool equal(const forest_iterator& y) const
00438 { return (node_m == y.node_m) && (edge_m == y.edge_m); }
00439
00440 node_t* node_m;
00441 std::size_t edge_m;
00442
00443 forest_iterator(node_t* node, std::size_t edge) :
00444 node_m(node), edge_m(edge) { }
00445 };
00446
00447
00448
00449
00450 template <typename T>
00451 class forest_const_iterator : public boost::iterator_facade<forest_const_iterator<T>,
00452 const T,
00453 std::bidirectional_iterator_tag>
00454 {
00455 typedef boost::iterator_facade<forest_const_iterator<T>,
00456 const T,
00457 std::bidirectional_iterator_tag> inherited_t;
00458 public:
00459 typedef typename inherited_t::reference reference;
00460 typedef typename inherited_t::difference_type difference_type;
00461 typedef typename inherited_t::value_type value_type;
00462
00463 forest_const_iterator() :
00464 node_m(0), edge_m(forest_leading_edge) { }
00465
00466 forest_const_iterator(const forest_const_iterator& x) :
00467 node_m(x.node_m), edge_m(x.edge_m) { }
00468
00469 forest_const_iterator(const forest_iterator<T>& x) :
00470 node_m(x.node_m), edge_m(x.edge_m) { }
00471
00472 std::size_t edge() const { return edge_m; }
00473 std::size_t& edge() { return edge_m; }
00474 bool equal_node(forest_const_iterator const& y) const { return node_m == y.node_m; }
00475
00476 private:
00477 friend class adobe::forest<value_type>;
00478 friend class boost::iterator_core_access;
00479 template <typename> friend class forest_const_iterator;
00480 friend struct unsafe::set_next_fn<forest_const_iterator>;
00481
00482 typedef const node<T> node_t;
00483
00484 reference dereference() const { return node_m->data_m; }
00485
00486 void increment()
00487 {
00488 node_t* next(node_m->link(edge_m, node_t::next_s));
00489
00490 if (edge_m) edge_m = std::size_t(next != node_m);
00491 else edge_m = std::size_t(next->link(forest_leading_edge, node_t::prior_s) == node_m);
00492
00493 node_m = next;
00494 }
00495
00496 void decrement()
00497 {
00498 node_t* next(node_m->link(edge_m, node_t::prior_s));
00499
00500 if (edge_m) edge_m = std::size_t(next->link(forest_trailing_edge, node_t::next_s) != node_m);
00501 else edge_m = std::size_t(next == node_m);
00502
00503 node_m = next;
00504 }
00505
00506 bool equal(const forest_const_iterator& y) const
00507 { return (node_m == y.node_m) && (edge_m == y.edge_m); }
00508
00509 node_t* node_m;
00510 std::size_t edge_m;
00511
00512 forest_const_iterator(node_t* node, std::size_t edge) :
00513 node_m(node), edge_m(edge) { }
00514 };
00515
00516
00517
00518
00519 }
00520 #endif
00521
00522
00523
00524 namespace unsafe {
00525
00526 template <typename T>
00527 struct set_next_fn<implementation::forest_iterator<T> >
00528 {
00529 void operator()(implementation::forest_iterator<T> x, implementation::forest_iterator<T> y) const
00530 {
00531 typedef typename implementation::node<T> node_t;
00532
00533 x.node_m->link(x.edge(), node_t::next_s) = y.node_m;
00534 y.node_m->link(y.edge(), node_t::prior_s) = x.node_m;
00535 }
00536 };
00537
00538 }
00539
00540
00541
00542 template <typename T>
00543 class forest
00544 {
00545 private:
00546 typedef implementation::node<T> node_t;
00547 friend class child_adaptor<forest<T> >;
00548 public:
00549
00550 typedef T& reference;
00551 typedef const T& const_reference;
00552 typedef implementation::forest_iterator<T> iterator;
00553 typedef implementation::forest_const_iterator<T> const_iterator;
00554 typedef std::size_t size_type;
00555 typedef std::ptrdiff_t difference_type;
00556 typedef T value_type;
00557 typedef T* pointer;
00558 typedef const T* const_pointer;
00559 typedef reverse_fullorder_iterator<iterator> reverse_iterator;
00560 typedef reverse_fullorder_iterator<const_iterator> const_reverse_iterator;
00561
00562 typedef adobe::child_iterator<iterator> child_iterator;
00563
00564
00565
00566
00567 typedef adobe::child_iterator<const_iterator> const_child_iterator;
00568 typedef std::reverse_iterator<child_iterator> reverse_child_iterator;
00569
00570 typedef edge_iterator<iterator, forest_leading_edge> preorder_iterator;
00571 typedef edge_iterator<const_iterator, forest_leading_edge> const_preorder_iterator;
00572 typedef edge_iterator<iterator, forest_trailing_edge> postorder_iterator;
00573 typedef edge_iterator<const_iterator, forest_trailing_edge> const_postorder_iterator;
00574
00575 #if !defined(ADOBE_NO_DOCUMENTATION)
00576 forest();
00577 ~forest() { clear(); }
00578
00579 forest(const forest&);
00580 forest& operator=(forest x) { this->swap(x); return *this; }
00581
00582 void swap(forest&);
00583 #endif
00584
00585 size_type size() const;
00586 size_type size();
00587 size_type max_size() const { return size_type(-1); }
00588 bool size_valid() const { return size_m != 0 || empty(); }
00589 bool empty() const { return begin() == end(); }
00590
00591
00592 iterator root() { return iterator(tail(), forest_leading_edge); }
00593
00594 iterator begin() { return ++root(); }
00595 iterator end() { return iterator(tail(), forest_trailing_edge); }
00596 const_iterator begin() const { return ++const_iterator(tail(), forest_leading_edge); }
00597 const_iterator end() const { return const_iterator(tail(), forest_trailing_edge); }
00598
00599 reverse_iterator rbegin() { return reverse_iterator(end()); }
00600 reverse_iterator rend() { return reverse_iterator(begin()); }
00601 reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00602 reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00603
00604 reference front() { assert(!empty()); return *begin(); }
00605 const_reference front() const { assert(!empty()); return *begin(); }
00606 reference back() { assert(!empty()); return *(--end()); }
00607 const_reference back() const { assert(!empty()); return *(--end()); }
00608
00609
00610 void clear()
00611 {
00612 erase(begin(), end());
00613 assert(empty());
00614 }
00615
00616 iterator erase(const iterator& position);
00617 iterator erase(const iterator& first, const iterator& last);
00618
00619 iterator insert(const iterator& position, const T& x)
00620 {
00621 iterator result(new node_t(x), true);
00622
00623 if (size_valid()) ++size_m;
00624
00625 unsafe::set_next(boost::prior(position), result);
00626 unsafe::set_next(boost::next(result), position);
00627
00628 return result;
00629 }
00630
00631 void push_front(const T& x) { insert(begin(), x); }
00632 void push_back(const T& x) { insert(end(), x); }
00633 void pop_front() { assert(!empty()); erase(begin()); }
00634 void pop_back() { assert(!empty()); erase(--end()); }
00635
00636 iterator insert(iterator position, const_child_iterator first, const_child_iterator last);
00637
00638 iterator splice(iterator position, forest<T>& x);
00639 iterator splice(iterator position, forest<T>& x, iterator i);
00640 iterator splice(iterator position, forest<T>& x, child_iterator first, child_iterator last);
00641 iterator splice(iterator position, forest<T>& x, child_iterator first, child_iterator last, size_type count);
00642
00643 iterator insert_parent(child_iterator front, child_iterator back, const T& x);
00644 void reverse(child_iterator first, child_iterator last);
00645
00646 private:
00647 #if !defined(ADOBE_NO_DOCUMENTATION)
00648
00649 friend class implementation::forest_iterator<value_type>;
00650 friend class implementation::forest_const_iterator<value_type>;
00651 friend struct unsafe::set_next_fn<iterator>;
00652
00653
00654 #if 0
00655 struct node_base
00656 {
00657 enum next_prior_t
00658 {
00659 prior_s,
00660 next_s
00661 };
00662
00663 typedef node* node_ptr;
00664 typedef node_ptr& reference;
00665
00666 node_base()
00667 {
00668
00669 nodes_m[forest_leading_edge][std::size_t(next_s)] = static_cast<node*>(this);
00670 nodes_m[forest_trailing_edge][std::size_t(prior_s)] = static_cast<node*>(this);
00671 }
00672
00673 node_ptr& link(std::size_t edge, next_prior_t link)
00674 { return nodes_m[edge][std::size_t(link)]; }
00675
00676 node_ptr link(std::size_t edge, next_prior_t link) const
00677 { return nodes_m[edge][std::size_t(link)]; }
00678
00679 node_ptr nodes_m[2][2];
00680 };
00681
00682 struct node : public node_base
00683 {
00684 explicit node(const value_type& data) : data_m(data) { }
00685
00686 value_type data_m;
00687 };
00688
00689 #endif
00690
00691 size_type size_m;
00692 implementation::node_base<node_t> tail_m;
00693
00694 node_t* tail() { return static_cast<node_t*>(&tail_m); }
00695 const node_t* tail() const { return static_cast<const node_t*>(&tail_m); }
00696 #endif
00697 };
00698
00699
00700
00701 template <typename T>
00702 bool operator==(const forest<T>& x, const forest<T>& y)
00703 {
00704 if (x.size() != y.size()) return false;
00705
00706 for (typename forest<T>::const_iterator first(x.begin()), last(x.end()), pos(y.begin());
00707 first != last; ++first, ++pos)
00708 {
00709 if (first.edge() != pos.edge()) return false;
00710 if (first.edge() && (*first != *pos)) return false;
00711 }
00712
00713 return true;
00714 }
00715
00716
00717
00718 template <typename T>
00719 bool operator!=(const forest<T>& x, const forest<T>& y)
00720 { return !(x == y); }
00721
00722
00723
00724 namespace unsafe {
00725
00726 template <typename I>
00727 struct set_next_fn<child_iterator<I> >
00728 {
00729 void operator()(child_iterator<I> x, child_iterator<I> y)
00730 {
00731 unsafe::set_next(pivot_of(x.base()), y.base());
00732 }
00733 };
00734
00735 }
00736
00737
00738
00739 #if !defined(ADOBE_NO_DOCUMENTATION)
00740
00741 template <typename T>
00742 forest<T>::forest() :
00743 size_m(0)
00744 {
00745 unsafe::set_next(end(), root());
00746 }
00747
00748
00749
00750 template <typename T>
00751 forest<T>::forest(const forest& x) :
00752 size_m(0)
00753 {
00754 unsafe::set_next(end(), root());
00755
00756 insert(begin(), const_child_iterator(x.begin()), const_child_iterator(x.end()));
00757 }
00758
00759
00760
00761 template <typename T>
00762 void forest<T>::swap(forest& tree)
00763 {
00764 size_type old_size(size_valid() ? 0 : size());
00765 iterator last(splice(end(), tree));
00766 tree.splice(tree.end(), *this, child_iterator(begin()), child_iterator(last), old_size);
00767 }
00768
00769 #endif
00770
00771
00772
00773 template <typename T>
00774 typename forest<T>::size_type forest<T>::size()
00775 {
00776 if (!size_valid())
00777 {
00778 const_preorder_iterator first(begin());
00779 const_preorder_iterator last(end());
00780
00781 size_m = size_type(std::distance(first, last));
00782 }
00783
00784 return size_m;
00785 }
00786
00787
00788
00789 template <typename T>
00790 typename forest<T>::size_type forest<T>::size() const
00791 {
00792 if (size_valid()) return size_m;
00793
00794 const_preorder_iterator first(begin());
00795 const_preorder_iterator last(end());
00796
00797 return size_type(std::distance(first, last));
00798 }
00799
00800
00801
00802 template <typename T>
00803 typename forest<T>::iterator forest<T>::erase(const iterator& first, const iterator& last)
00804 {
00805 difference_type stack_depth(0);
00806 iterator position(first);
00807
00808 while (position != last)
00809 {
00810 if (position.edge() == forest_leading_edge)
00811 {
00812 ++stack_depth;
00813 ++position;
00814 }
00815 else
00816 {
00817 if (stack_depth > 0) position = erase(position);
00818 else ++position;
00819 stack_depth = std::max<difference_type>(0, stack_depth - 1);
00820 }
00821 }
00822 return last;
00823 }
00824
00825
00826
00827 template <typename T>
00828 void swap(forest<T>& x, forest<T>& y)
00829 { x.swap(y); }
00830
00831
00832
00833 template <typename T>
00834 typename forest<T>::iterator forest<T>::erase(const iterator& position)
00835 {
00836
00837
00838
00839
00840
00841
00842 if (size_valid()) --size_m;
00843
00844 iterator leading_prior(boost::prior(leading_of(position)));
00845 iterator leading_next(boost::next(leading_of(position)));
00846 iterator trailing_prior(boost::prior(trailing_of(position)));
00847 iterator trailing_next(boost::next(trailing_of(position)));
00848
00849 if (has_children(position))
00850 {
00851 unsafe::set_next(leading_prior, leading_next);
00852 unsafe::set_next(trailing_prior, trailing_next);
00853 }
00854 else
00855 {
00856 unsafe::set_next(leading_prior, trailing_next);
00857 }
00858
00859 delete position.node_m;
00860
00861 return position.edge() ? boost::next(leading_prior) : trailing_next;
00862 }
00863
00864
00865
00866 template <typename T>
00867 typename forest<T>::iterator forest<T>::splice(iterator position, forest<T>& x)
00868 {
00869 return splice(position, x, child_iterator(x.begin()), child_iterator(x.end()),
00870 x.size_valid() ? x.size() : 0);
00871 }
00872
00873
00874
00875 template <typename T>
00876 typename forest<T>::iterator forest<T>::splice(iterator position, forest<T>& x, iterator i)
00877 {
00878 i.edge() = forest_leading_edge;
00879 return splice(position, x, child_iterator(i), ++child_iterator(i), has_children(i) ? 0 : 1);
00880 }
00881
00882
00883
00884 template <typename T>
00885 typename forest<T>::iterator forest<T>::insert(iterator pos, const_child_iterator f,
00886 const_child_iterator l)
00887 {
00888 for (const_iterator first(f.base()), last(l.base()); first != last; ++first, ++pos)
00889 {
00890 if (first.edge()) pos = insert(pos, *first);
00891 }
00892
00893 return pos;
00894 }
00895
00896
00897
00898 template <typename T>
00899 typename forest<T>::iterator forest<T>::splice(iterator pos, forest<T>& x, child_iterator first,
00900 child_iterator last, size_type count)
00901 {
00902 if (first == last || first.base() == pos) return pos;
00903
00904 if (&x != this)
00905 {
00906 if (count)
00907 {
00908 if (size_valid()) size_m += count;
00909 if (x.size_valid()) x.size_m -= count;
00910 }
00911 else
00912 {
00913 size_m = 0;
00914 x.size_m = 0;
00915 }
00916 }
00917
00918 iterator back(boost::prior(last.base()));
00919
00920 unsafe::set_next(boost::prior(first), last);
00921
00922 unsafe::set_next(boost::prior(pos), first.base());
00923 unsafe::set_next(back, pos);
00924
00925 return first.base();
00926 }
00927
00928
00929
00930 template <typename T>
00931 inline typename forest<T>::iterator forest<T>::splice(iterator pos, forest<T>& x,
00932 child_iterator first, child_iterator last)
00933 { return splice(pos, x, first, last, 0); }
00934
00935
00936
00937 template <typename T>
00938 typename forest<T>::iterator forest<T>::insert_parent(child_iterator first, child_iterator last,
00939 const T& x)
00940 {
00941 iterator result(insert(last.base(), x));
00942 if (first == last) return result;
00943 splice(trailing_of(result), *this, first, child_iterator(result));
00944 return result;
00945 }
00946
00947
00948
00949 template <typename T>
00950 void forest<T>::reverse(child_iterator first, child_iterator last)
00951 {
00952 iterator prior(first.base());
00953 --prior;
00954 first = unsafe::reverse_nodes(first, last);
00955 unsafe::set_next(prior, first.base());
00956 }
00957
00958
00959
00960 template <typename Forest>
00961 class child_adaptor
00962 {
00963 public:
00964 typedef Forest forest_type;
00965 typedef typename Forest::value_type value_type;
00966 typedef typename Forest::iterator iterator_type;
00967 typedef typename Forest::reference reference;
00968 typedef typename Forest::const_reference const_reference;
00969 typedef typename Forest::difference_type difference_type;
00970 typedef typename Forest::child_iterator iterator;
00971
00972 child_adaptor(forest_type& f, iterator_type& i) :
00973 forest_m(f), iterator_m(i)
00974 { }
00975
00976 iterator& back() { return *(--child_end(iterator_m)); }
00977 iterator& front() { return *(child_begin(iterator_m)); }
00978
00979 void push_back(const value_type& x) { forest_m.insert(child_end(iterator_m).base(), x); }
00980 void push_front(const value_type& x) { forest_m.insert(child_begin(iterator_m).base(), x); }
00981
00982 void pop_back() { forest_m.erase(--child_end(iterator_m).base()); }
00983 void pop_front() { forest_m.erase(child_begin(iterator_m).base()); }
00984
00985 private:
00986 child_adaptor();
00987
00988 forest_type& forest_m;
00989 iterator_type& iterator_m;
00990 };
00991
00992
00993
00994 template <typename I>
00995 child_iterator<I> child_begin(const I& x)
00996 { return child_iterator<I>(boost::next(leading_of(x))); }
00997
00998
00999
01000 template <typename I>
01001 child_iterator<I> child_end(const I& x)
01002 { return child_iterator<I>(trailing_of(x)); }
01003
01004
01005
01006
01007
01008
01009
01010
01021 template <typename R, typename P>
01022 inline std::pair<filter_fullorder_iterator<typename boost::range_iterator<R>::type, P>,
01023 filter_fullorder_iterator<typename boost::range_iterator<R>::type, P> >
01024 filter_fullorder_range(R& x, P p)
01025 {
01026 typedef filter_fullorder_iterator<typename boost::range_iterator<R>::type, P> iterator;
01027
01028 return std::make_pair(iterator(boost::begin(x), boost::end(x), p), iterator(boost::end(x), boost::end(x), p));
01029 }
01030
01041 template <typename R, typename P>
01042 inline std::pair<filter_fullorder_iterator<typename boost::range_const_iterator<R>::type, P>,
01043 filter_fullorder_iterator<typename boost::range_const_iterator<R>::type, P> >
01044 filter_fullorder_range(const R& x, P p)
01045 {
01046 typedef filter_fullorder_iterator<typename boost::range_const_iterator<R>::type, P> iterator;
01047
01048 return std::make_pair(iterator(p, boost::begin(x), boost::end(x)), iterator(p, boost::end(x), boost::end(x)));
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01073 template <typename R>
01074 inline std::pair<reverse_fullorder_iterator<typename boost::range_iterator<R>::type>,
01075 reverse_fullorder_iterator<typename boost::range_iterator<R>::type> >
01076 reverse_fullorder_range(R& x)
01077 {
01078 typedef reverse_fullorder_iterator<typename boost::range_iterator<R>::type> iterator;
01079
01080 return std::make_pair(iterator(boost::end(x)), iterator(boost::begin(x)));
01081 }
01082
01092 template <typename R>
01093 inline std::pair<reverse_fullorder_iterator<typename boost::range_const_iterator<R>::type>,
01094 reverse_fullorder_iterator<typename boost::range_const_iterator<R>::type> >
01095 reverse_fullorder_range(const R& x)
01096 {
01097 typedef reverse_fullorder_iterator<typename boost::range_const_iterator<R>::type> iterator;
01098
01099 return std::make_pair(iterator(boost::end(x)), iterator(boost::begin(x)));
01100 }
01101
01102
01103
01104
01114 template <typename R>
01115 inline std::pair<depth_fullorder_iterator<typename boost::range_iterator<R>::type>,
01116 depth_fullorder_iterator<typename boost::range_iterator<R>::type> >
01117 depth_range(R& x)
01118 {
01119 typedef depth_fullorder_iterator<typename boost::range_iterator<R>::type> iterator;
01120
01121 return std::make_pair(iterator(boost::begin(x)), iterator(boost::end(x)));
01122 }
01123
01133 template <typename R>
01134 inline std::pair<depth_fullorder_iterator<typename boost::range_const_iterator<R>::type>,
01135 depth_fullorder_iterator<typename boost::range_const_iterator<R>::type> >
01136 depth_range(const R& x)
01137 {
01138 typedef depth_fullorder_iterator<typename boost::range_const_iterator<R>::type> iterator;
01139
01140 return std::make_pair(iterator(boost::begin(x)), iterator(boost::end(x)));
01141 }
01142
01143
01144
01154 template <typename R>
01155 inline std::pair<edge_iterator<typename boost::range_iterator<R>::type, forest_trailing_edge>,
01156 edge_iterator<typename boost::range_iterator<R>::type, forest_trailing_edge> >
01157 postorder_range(R& x)
01158 {
01159 typedef edge_iterator<typename boost::range_iterator<R>::type, forest_trailing_edge> iterator;
01160
01161 return std::make_pair(iterator(boost::begin(x)), iterator(boost::end(x)));
01162 }
01163
01173 template <typename R>
01174 inline std::pair<edge_iterator<typename boost::range_const_iterator<R>::type, forest_trailing_edge>,
01175 edge_iterator<typename boost::range_const_iterator<R>::type, forest_trailing_edge> >
01176 postorder_range(const R& x)
01177 {
01178 typedef edge_iterator<typename boost::range_const_iterator<R>::type, forest_trailing_edge> iterator;
01179
01180 return std::make_pair(iterator(boost::begin(x)), iterator(boost::end(x)));
01181 }
01182
01183
01184
01194 template <typename R>
01195 inline std::pair<edge_iterator<typename boost::range_iterator<R>::type, forest_leading_edge>,
01196 edge_iterator<typename boost::range_iterator<R>::type, forest_leading_edge> >
01197 preorder_range(R& x)
01198 {
01199 typedef edge_iterator<typename boost::range_iterator<R>::type, forest_leading_edge> iterator;
01200
01201 return std::make_pair(iterator(boost::begin(x)), iterator(boost::end(x)));
01202 }
01203
01213 template <typename R>
01214 inline std::pair<edge_iterator<typename boost::range_const_iterator<R>::type, forest_leading_edge>,
01215 edge_iterator<typename boost::range_const_iterator<R>::type, forest_leading_edge> >
01216 preorder_range(const R& x)
01217 {
01218 typedef edge_iterator<typename boost::range_const_iterator<R>::type, forest_leading_edge> iterator;
01219
01220 return std::make_pair(iterator(boost::begin(x)), iterator(boost::end(x)));
01221 }
01222
01223
01224
01225 }
01226
01227
01228
01229 #endif
01230
01231