stlab.adobe.com Adobe Systems Incorporated

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 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google