diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-03 20:50:12 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-03 20:50:12 +0000 |
commit | 97fdd16c528bfd7f6ada18b97c3ea9b37e8bbe8f (patch) | |
tree | 078a19fbc040500f4e4e9726c13aed5b340c3695 /ui | |
parent | 6786bf4014c791f84d916c6c3d2881829032c29e (diff) | |
download | chromium_src-97fdd16c528bfd7f6ada18b97c3ea9b37e8bbe8f.zip chromium_src-97fdd16c528bfd7f6ada18b97c3ea9b37e8bbe8f.tar.gz chromium_src-97fdd16c528bfd7f6ada18b97c3ea9b37e8bbe8f.tar.bz2 |
Adds back BookmarkNode::IsVisible. Turns out we want to conditionally
show a node, so we need it. *SIGH*
For the most part this is a revert of
http://codereview.chromium.org/8759017/, so don't feel you need to
review it that deeply.
BUG=102714
TEST=none
TBR=ben@chromium.org
Review URL: http://codereview.chromium.org/8772064
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112897 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/models/tree_node_iterator.h | 38 | ||||
-rw-r--r-- | ui/base/models/tree_node_iterator_unittest.cc | 40 |
2 files changed, 74 insertions, 4 deletions
diff --git a/ui/base/models/tree_node_iterator.h b/ui/base/models/tree_node_iterator.h index 26d6dea..5a05df9 100644 --- a/ui/base/models/tree_node_iterator.h +++ b/ui/base/models/tree_node_iterator.h @@ -23,7 +23,27 @@ namespace ui { template <class NodeType> class TreeNodeIterator { public: - explicit TreeNodeIterator(NodeType* node) { + // This contructor accepts an optional filter function |prune| which could be + // used to prune complete branches of the tree. The filter function will be + // evaluated on each tree node and if it evaluates to true the node and all + // its descendants will be skipped by the iterator. + TreeNodeIterator(NodeType* node, bool (*prune)(NodeType*)) + : prune_(prune) { + int index = 0; + + // Move forward through the children list until the first non prunable node. + // This is to satisfy the iterator invariant that the current index in the + // Position at the top of the _positions list must point to a node the + // iterator will be returning. + for (; index < node->child_count(); ++index) + if (!prune || !prune(node->GetChild(index))) + break; + + if (index < node->child_count()) + positions_.push(Position<NodeType>(node, index)); + } + + explicit TreeNodeIterator(NodeType* node) : prune_(NULL) { if (!node->empty()) positions_.push(Position<NodeType>(node, 0)); } @@ -47,9 +67,18 @@ class TreeNodeIterator { // Iterate over result's children. positions_.push(Position<NodeType>(result, 0)); - while (!positions_.empty() && - positions_.top().index >= positions_.top().node->child_count()) { - positions_.pop(); // This Position is all processed, move to the next. + // Advance to next valid node by skipping over the pruned nodes and the + // empty Positions. At the end of this loop two cases are possible: + // - the current index of the top() Position points to a valid node + // - the _position list is empty, the iterator has_next() will return false. + while (!positions_.empty()) { + if (positions_.top().index >= positions_.top().node->child_count()) + positions_.pop(); // This Position is all processed, move to the next. + else if (prune_ && + prune_(positions_.top().node->GetChild(positions_.top().index))) + positions_.top().index++; // Prune the branch. + else + break; // Now positioned at the next node to be returned. } return result; @@ -66,6 +95,7 @@ class TreeNodeIterator { }; std::stack<Position<NodeType> > positions_; + bool (*prune_)(NodeType*); DISALLOW_COPY_AND_ASSIGN(TreeNodeIterator); }; diff --git a/ui/base/models/tree_node_iterator_unittest.cc b/ui/base/models/tree_node_iterator_unittest.cc index 13140e9..0aefe4d 100644 --- a/ui/base/models/tree_node_iterator_unittest.cc +++ b/ui/base/models/tree_node_iterator_unittest.cc @@ -38,4 +38,44 @@ TEST(TreeNodeIteratorTest, Test) { ASSERT_FALSE(iterator.has_next()); } +static bool PruneOdd(TreeNodeWithValue<int>* node) { + return node->value % 2; +} + +static bool PruneEven(TreeNodeWithValue<int>* node) { + return !(node->value % 2); +} + +// The tree used for testing: +// * + 1 +// + 2 +// + 3 + 4 + 5 +// + 7 + +TEST(TreeNodeIteratorPruneTest, Test) { + TreeNodeWithValue<int> root; + root.Add(new TreeNodeWithValue<int>(1), 0); + root.Add(new TreeNodeWithValue<int>(2), 1); + TreeNodeWithValue<int>* f3 = new TreeNodeWithValue<int>(3); + root.Add(f3, 2); + TreeNodeWithValue<int>* f4 = new TreeNodeWithValue<int>(4); + f3->Add(f4, 0); + f4->Add(new TreeNodeWithValue<int>(5), 0); + f3->Add(new TreeNodeWithValue<int>(7), 1); + + TreeNodeIterator<TreeNodeWithValue<int> > oddIterator(&root, PruneOdd); + ASSERT_TRUE(oddIterator.has_next()); + ASSERT_EQ(2, oddIterator.Next()->value); + ASSERT_FALSE(oddIterator.has_next()); + + TreeNodeIterator<TreeNodeWithValue<int> > evenIterator(&root, PruneEven); + ASSERT_TRUE(evenIterator.has_next()); + ASSERT_EQ(1, evenIterator.Next()->value); + ASSERT_TRUE(evenIterator.has_next()); + ASSERT_EQ(3, evenIterator.Next()->value); + ASSERT_TRUE(evenIterator.has_next()); + ASSERT_EQ(7, evenIterator.Next()->value); + ASSERT_FALSE(evenIterator.has_next()); +} + } // namespace ui |