forest.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 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 NOTE (sparent) : These are the edge index value - trailing as 0 and leading as 1 is done to 00035 reflect that it used to be a leading bool value. Changing the order of this enum requires 00036 code review as some code relies on the test for leading. 00037 */ 00038 00039 enum 00040 { 00041 forest_trailing_edge, 00042 forest_leading_edge 00043 }; 00044 00045 /*************************************************************************************************/ 00046 00047 template <typename I> // I models FullorderIterator 00048 inline void pivot(I& i) { i.edge() ^= 1; } 00049 00050 template <typename I> // I models FullorderIterator 00051 inline I pivot_of(I i) { pivot(i); return i; } 00052 00053 /*************************************************************************************************/ 00054 00055 template <typename I> // I models a FullorderIterator 00056 inline I leading_of(I i) { i.edge() = forest_leading_edge; return i; } 00057 00058 template <typename I> // I models a FullorderIterator 00059 inline I trailing_of(I i) { i.edge() = forest_trailing_edge; return i; } 00060 00061 /*************************************************************************************************/ 00062 00063 template <typename I> // I models FullorderIterator 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> // I models FullorderIterator 00073 bool has_children(const I& i) 00074 { return !i.equal_node(boost::next(leading_of(i))); } 00075 00076 /*************************************************************************************************/ 00077 00078 template <typename I> // I models FullorderIterator 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> // I models FullorderIterator 00097 I find_edge(I x, std::size_t edge) { while (x.edge() != edge) ++x; return x; } 00098 00099 template <typename I> // I models FullorderIterator 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> // I models FullorderIterator 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 I need to establish dereferencable range vs. traversable range. 00128 00129 Here [f, l) must be a dereferencable range and p() will not be applied outside that range 00130 although the iterators may travel beyond that range. 00131 */ 00132 00133 template < typename I, // I models a Forest 00134 typename P> // P models UnaryPredicate of value_type(I) 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 // Precondition: l is on a leading edge 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 // Precondition: f is on a trailing edge 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 REVISIT (sparent) : This is an interesting case - an edge is a property of an iterator but it 00226 is determined by examining a vertex in the graph. Here we need to examine the prior vertex 00227 to determine the edge. If the range is empty (or we are at the "end" of the range) then this 00228 examination is questionable. 00229 00230 We let it go, because we know the forest structure is an infinite loop through the root. One 00231 answer to this would be to construct a reverse iterator which was not "off by one" for forest - 00232 but that might break people who assume base() is off by one for a reverse iterator, and it still 00233 assumes a root(). 00234 */ 00235 00236 template <typename I> // I models a FullorderIterator 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> // I models FullorderIterator 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> // derived class 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 // leading is 1, trailing is 0 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> // T models Regular 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> // T is value_type 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> // T is value_type 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 } // namespace implementation 00520 #endif 00521 00522 /*************************************************************************************************/ 00523 00524 namespace unsafe { 00525 00526 template <typename T> // T is node<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 } // namespace unsafe 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 // types 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 /* qualification needed since: A name N used in a class S shall refer to the same declaration 00564 in its context and when re-evaluated in the completed scope of 00565 S. */ 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(); } // Don't test size which may be expensive 00590 00591 // iterators 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 // modifiers 00610 void clear() 00611 { 00612 erase(begin(), end()); 00613 assert(empty()); // Make sure our erase is correct 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 // leading is 1, trailing is 0 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> // I models a FullorderIterator 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 } // namespace unsafe 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 NOTE (sparent) : After the first call to set_next() the invariants of the forest are 00838 violated and we can't determing leading/trailing if we navigate from the effected node. 00839 So we gather all the iterators up front then do the set_next calls. 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(); // not defined 00987 00988 forest_type& forest_m; 00989 iterator_type& iterator_m; 00990 }; 00991 00992 /*************************************************************************************************/ 00993 00994 template <typename I> // I models FullorderIterator 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> // I models FullorderIterator 01001 child_iterator<I> child_end(const I& x) 01002 { return child_iterator<I>(trailing_of(x)); } 01003 01004 /*************************************************************************************************/ 01005 01006 /* 01007 NOTE (fbrereto) : The Doxygen documentation is inline for the functions below because their 01008 signatures are particularly prone to translation error. 01009 */ 01010 01021 template <typename R, typename P> // R models FullorderRange 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> // R models FullorderRange 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 REVISIT (sparent) : There should be some way to generalize this into a make_range - which is 01055 specialized. 01056 01057 One option - 01058 01059 reverse_range(R& x) 01060 01061 Hmmm - maybe reverse_fullorder_iterator should be a specialization of std::reverse_iterator? 01062 */ 01063 01073 template <typename R> // R models FullorderRange 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> // R models FullorderRange 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> // R models FullorderRange 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> // R models FullorderRange 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> // R models FullorderRange 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> // R models FullorderRange 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> // R models FullorderRange 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> // R models FullorderRange 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 } // namespace adobe 01226 01227 /*************************************************************************************************/ 01228 01229 #endif 01230 01231 /*************************************************************************************************/ |