|
Boost-Commit : |
From: ockham_at_[hidden]
Date: 2008-07-06 10:23:47
Author: bernhard.reiter
Date: 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
New Revision: 47133
URL: http://svn.boost.org/trac/boost/changeset/47133
Log:
Introducing root_tracking_cursor.
Text files modified:
sandbox/SOC/2006/tree/trunk/TODO | 21 ++--------
sandbox/SOC/2006/tree/trunk/boost/tree/ascending_cursor.hpp | 75 +++++++++++++++++++++++++++++++++++++
sandbox/SOC/2006/tree/trunk/boost/tree/binary_tree.hpp | 20 ----------
sandbox/SOC/2006/tree/trunk/boost/tree/cursor_adaptor.hpp | 80 ++++++++++++++++++++-------------------
sandbox/SOC/2006/tree/trunk/boost/tree/detail/cursor/nary.hpp | 22 -----------
sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/_order.hpp | 2
sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/inorder.hpp | 1
sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/postorder.hpp | 1
sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/preorder.hpp | 1
sandbox/SOC/2006/tree/trunk/libs/tree/test/iterator_algorithm_test.cpp | 31 ++++++++++++---
10 files changed, 145 insertions(+), 109 deletions(-)
Modified: sandbox/SOC/2006/tree/trunk/TODO
==============================================================================
--- sandbox/SOC/2006/tree/trunk/TODO (original)
+++ sandbox/SOC/2006/tree/trunk/TODO 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -19,6 +19,11 @@
(insert()/insert_above()), trees with values only at the leaves (makes sense in combination
with "upwards" insertion"), etc.
* === The is_root problem() and its solution ===
+ Get rid of checks for/assignments to root in pre/post/inorder algorithms,
+ as they are otherwise limited to "whole" trees and cannot be applied to subtrees.
+ In order to work for subtrees, it's probable that we need at least an int to store
+ the current depth.
+ Solution:
Introduce a root tracking cursor concept providing c.is_root(). *order::forward(), back(),
next() and prior() functions as well as *order::iterators then require this concept.
Write a root_tracking_cursor adaptor that does exactly that, with suitable specializations
@@ -26,22 +31,6 @@
(Why? Because any root_tracker object would have to be
passed along with a cursor, plus in- or decremented when going down or up in the hierarchy,
resp. This kind of naturally suggests some kind of encapsulation/adaptation.)
- (Earlier thoughts:)
- Get rid of checks for/assignments to root in pre/post/inorder algorithms,
- as they are otherwise limited to "whole" trees and cannot be applied to subtrees.
- In order to work for subtrees, it's probable that we need at least an int to store
- the current depth. (Which, in turn, would make the free-standing forward/back/next/prior
- algorithms etc. more or less useless without that piece of extra information and would
- only leave us with the iterators to store it.)
- -> This is going to be done by the RootTracker object, which I personally hate,
- but I don't see much of a choice for iterative traversal of subtrees other than that
- (and haven't found any on the Web, either).
- Our options, in more detail:
- * Saving a copy of root, obviously. (Only comparison, no later calculation of depth involved)
- * Iterators based on ascending cursor shouldn't check for size==1, but for size==root_size,
- where root_size is the size of the stack with all cursors up to the root cursor
- are pushed. (Comparison, no calculation)
- * Some color map approach? (Cf BGL, Knuth?)
* Do we want/need an O(1) inorder_begin() for binary_tree?
Does Gnu's rb_tree (used in std::map) have one?
* Is it really a good idea to use InCursor::size_type for size(Cursor)?
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/ascending_cursor.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/ascending_cursor.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/ascending_cursor.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -5,7 +5,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
/**
- * @file ascending.hpp
+ * @file ascending_cursor.hpp
* Ascending cursor adaptor implementation
*/
@@ -15,6 +15,8 @@
#include <boost/tree/cursor.hpp>
#include <boost/tree/cursor_facade.hpp>
+#include <boost/tree/root_tracking_cursor.hpp>
+
#include <boost/tree/detail/iterator/ascending.hpp>
#include <boost/mpl/eval_if.hpp>
@@ -106,6 +108,8 @@
friend class boost::iterator_core_access;
friend class boost::tree::cursor_core_access;
+ friend class root_tracking_cursor<self_type>;
+
// friend
// typename ascending::iterator<self_type>::difference_type
// boost::tree::distance<>(
@@ -205,6 +209,75 @@
- ascending_cursor<Cursor>(iter1).m_s.size();
}
+template <class Cursor>
+class root_tracking_cursor< ascending_cursor<Cursor> >
+: public cursor_adaptor<root_tracking_cursor< ascending_cursor<Cursor> >
+ , ascending_cursor<Cursor>
+ , boost::use_default
+ , typename cursor_horizontal_traversal<
+ ascending_cursor<Cursor> >::type
+ , bidirectional_traversal_tag
+ > {
+ private:
+ struct enabler {};
+ typedef root_tracking_cursor< ascending_cursor<Cursor> > self_type;
+ public:
+ typedef typename ascending_cursor<Cursor>::value_type value_type;
+
+ // Container-specific:
+ typedef typename ascending_cursor<Cursor>::size_type size_type;
+
+ // Cursor-specific
+ typedef root_tracking_cursor< ascending_cursor<Cursor> > cursor;
+ typedef root_tracking_cursor<
+ typename ascending_cursor<Cursor>::const_cursor > const_cursor;
+
+ // Container-specific:
+ typedef cursor iterator;
+ typedef const_cursor const_iterator;
+
+ template <class OtherCursor>
+ struct rebind {
+ typedef root_tracking_cursor< ascending_cursor<OtherCursor> > other;
+ };
+
+ root_tracking_cursor()
+ : root_tracking_cursor::cursor_adaptor_(), m_root_depth(1) {}
+
+ explicit root_tracking_cursor(ascending_cursor<Cursor> c)
+ : root_tracking_cursor::cursor_adaptor_(c), m_root_depth(c.m_s.size()) {}
+
+ template <class OtherCursor>
+ root_tracking_cursor(
+ root_tracking_cursor< ascending_cursor<OtherCursor> > const& other
+ , typename boost::enable_if<
+ boost::is_convertible<ascending_cursor<OtherCursor>*
+ , ascending_cursor<Cursor>*>
+ , enabler
+ >::type = enabler()
+ )
+ : root_tracking_cursor::cursor_adaptor_(other.base())
+ , m_root_depth(other.base().m_s.size()) {}
+
+ private:
+
+ std::size_t m_root_depth;
+
+ friend class boost::iterator_core_access;
+ friend class boost::tree::cursor_core_access;
+
+// bool equal(cursor const& other) const
+// {
+// }
+
+public:
+ bool is_root() const
+ {
+ return this->base().m_s.size() == m_root_depth;
+ }
+};
+
+
} // namespace tree
} // namespace boost
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/binary_tree.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/binary_tree.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/binary_tree.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -557,26 +557,6 @@
x.swap(y);
}
-template <class Cursor>
-class binary_tree_root_tracker {
-
- public:
- binary_tree_root_tracker() {}
- binary_tree_root_tracker& operator++()
- {
- return *this;
- }
- binary_tree_root_tracker& operator--()
- {
- return *this;
- }
-
- bool is_root(Cursor c)
- {
- return (!c.parity() && (c != c.parent().begin()));
- }
-};
-
/**
* @brief Binary tree equality comparison.
* @param x A %binary_tree.
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/cursor_adaptor.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/cursor_adaptor.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/cursor_adaptor.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -18,6 +18,8 @@
#include <boost/tree/cursor_facade.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -139,46 +141,19 @@
, Difference
, Size>::size_type>
{
- friend class iterator_core_access;
- friend class cursor_core_access;
- typedef cursor_facade<Derived
- , Value
- , HorizontalTraversalOrCategory
- , VerticalTraversalOrCategory
- , Reference
- , Difference
- , Size> cursor_facade_;
-
- public:
- cursor_adaptor() {}
-
- explicit cursor_adaptor(Base const& cur) : m_cursor(cur)
- { }
-
- Base const& base() const
- { return m_cursor; }
-
- typedef typename cursor_facade_::iterator_category iterator_category;
-
- typedef typename cursor_facade_::horizontal_traversal horizontal_traversal;
- typedef typename cursor_facade_::vertical_traversal cursor_category;
-
- typedef Size size_type;
- typedef Base base_type;
-
- protected:
+protected:
typedef cursor_adaptor<Derived, Base, Value, HorizontalTraversalOrCategory,
VerticalTraversalOrCategory, Reference, Difference,
Size> cursor_adaptor_;
typedef eval_use_default<Derived
- , Base
- , Value
- , HorizontalTraversalOrCategory
- , VerticalTraversalOrCategory
- , Reference
- , Difference
- , Size> super_t;
+ , Base
+ , Value
+ , HorizontalTraversalOrCategory
+ , VerticalTraversalOrCategory
+ , Reference
+ , Difference
+ , Size> super_t;
Base const& base_reference() const
{ return m_cursor; }
@@ -186,8 +161,38 @@
Base& base_reference()
{ return m_cursor; }
- public:
+private:
+ Base m_cursor;
+
+ friend class iterator_core_access;
+ friend class cursor_core_access;
+
+ typedef cursor_facade<Derived
+ , typename super_t::value_type
+ , typename super_t::iterator_category
+ , typename super_t::vertical_traversal
+ , typename super_t::reference
+ , typename super_t::difference_type
+ , typename super_t::size_type> cursor_facade_;
+
+public:
+ typedef Base base_type;
+
+ typedef typename cursor_facade_::iterator_category iterator_category;
+
+ typedef typename cursor_facade_::horizontal_traversal horizontal_traversal;
+ typedef typename cursor_facade_::vertical_traversal cursor_category;
+
+ typedef typename cursor_facade_::size_type size_type;
+ cursor_adaptor() {}
+
+ explicit cursor_adaptor(Base const& cur) : m_cursor(cur)
+ { }
+
+ Base const& base() const
+ { return m_cursor; }
+
typename super_t::reference dereference() const
{
return *m_cursor;
@@ -253,9 +258,6 @@
{
m_cursor.to_parent();
}
-
-private:
- Base m_cursor;
};
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/detail/cursor/nary.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/detail/cursor/nary.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/detail/cursor/nary.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -98,28 +98,6 @@
base_pointer m_node;
size_type m_pos;
- class root_tracker {
- public:
- root_tracker() : depth(0) {}
- root_tracker& operator++()
- {
- ++depth;
- return *this;
- }
-
- root_tracker& operator--()
- {
- --depth;
- return *this;
- }
-
- bool is_root(cursor)
- {
- return !depth;
- }
- private:
- int depth;
- };
private:
friend class iterator_core_access;
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/_order.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/_order.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/_order.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -23,7 +23,7 @@
* Only works with ascending cursors.
*/
-template <class Cursor, class RootTracker = typename Cursor::root_tracker>
+template <class Cursor>
class iterator
: public boost::iterator_adaptor<iterator<Cursor>
, Cursor
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/inorder.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/inorder.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/inorder.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -18,7 +18,6 @@
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
-//#include <boost/test/minimal.hpp>
namespace boost {
namespace tree {
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/postorder.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/postorder.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/postorder.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -18,7 +18,6 @@
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
-//#include <boost/test/minimal.hpp>
namespace boost {
namespace tree {
Modified: sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/preorder.hpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/preorder.hpp (original)
+++ sandbox/SOC/2006/tree/trunk/boost/tree/detail/iterator/preorder.hpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -19,7 +19,6 @@
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
-//#include <boost/test/minimal.hpp>
namespace boost {
namespace tree {
Modified: sandbox/SOC/2006/tree/trunk/libs/tree/test/iterator_algorithm_test.cpp
==============================================================================
--- sandbox/SOC/2006/tree/trunk/libs/tree/test/iterator_algorithm_test.cpp (original)
+++ sandbox/SOC/2006/tree/trunk/libs/tree/test/iterator_algorithm_test.cpp 2008-07-06 10:23:44 EDT (Sun, 06 Jul 2008)
@@ -17,6 +17,7 @@
#include <boost/tree/algorithm.hpp>
#include <boost/tree/ascending_cursor.hpp>
+#include <boost/tree/root_tracking_cursor.hpp>
#include <boost/test/minimal.hpp>
@@ -83,12 +84,19 @@
return;
}
+void comparisons_using_rtc(binary_tree<int>::cursor c) {
+ comparisons(make_root_tracking_cursor(c));
+ return;
+}
+
/**
* Check all iterator traversals by comparing them to a recursive cursor
* algorithm output. Do that at different stages of the tree while adding
* elements to it, so different tree shapes are checked to be catered for
* by the iterator algorithms.
- * Do all that also using iterators wrapped around "explicit stack"-based cursors
+ *
+ * Afterwards, do all that using iterators wrapped around
+ * "explicit stack"-based cursors also.
*/
void compare_cursor_to_iterator_traversal() {
binary_tree<int> test_tree2;
@@ -97,51 +105,60 @@
binary_tree<int>::cursor c = test_tree2.insert(test_tree2.root(), 8);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
c = test_tree2.insert(c, 3);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
-
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
+
test_tree2.insert(c, 1);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
-
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
+
c = test_tree2.insert(++c, 6);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
test_tree2.insert(c, 4);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
-
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
+
test_tree2.insert(++c, 7);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
c = test_tree2.insert(test_tree2.root().end(), 10);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
c = test_tree2.insert(test_tree2.root().end().end(), 14);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
c = test_tree2.insert(c, 13);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
c = test_tree2.insert(c, 11);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
c = test_tree2.insert(++c, 12);
comparisons(test_tree2.root());
comparisons(make_ascending_cursor(test_tree2.root()));
-
- // FIXME: This requires subtree cursors to know their root.
- //underefed_for_each(test_tree2.root(), comparisons<binary_tree<int>::cursor>);
+ comparisons(make_root_tracking_cursor(test_tree2.root()));
underefed_for_each(test_tree2.root(), comparisons_using_ac);
+ underefed_for_each(test_tree2.root(), comparisons_using_rtc);
}
int test_main(int, char* [])
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk