From e604b55eac32f47174e1b04e118e540f3d4343e3 Mon Sep 17 00:00:00 2001 From: Arnaud Malapert Date: Thu, 14 Jun 2012 15:28:38 +0200 Subject: [PATCH] Add an iterator over the paths in a subtree defined by its root node (ctor parameter) (#16). --- src/network.cpp | 29 ++++++++++++++++++++-- src/network.hpp | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ test/main.cpp | 24 +++++++++++++------ 3 files changed, 108 insertions(+), 9 deletions(-) diff --git a/src/network.cpp b/src/network.cpp index a3efd99..72446cb 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -64,6 +64,15 @@ AncestorIterator FacilityNode::aend() { return AncestorIterator(NULL); } +//For AncestorIterator +PathIterator FacilityNode::pbegin() { + return PathIterator(this); +} + +PathIterator FacilityNode::pend() { + return PathIterator(NULL); +} + ostream & FacilityNode::toDotty(ostream & out) { out << getID(); @@ -381,7 +390,7 @@ LinkIterator::LinkIterator(FacilityNode* p) : current(NULL), end(NULL) { } LinkIterator& LinkIterator::operator ++() { - queue.push_back((*current)->getDestination()); + queue.push_back((*current)->getDestination()); //TODO Do not add leaves ? current++; while (current == end && !queue.empty()) { current = queue.front()->cbegin(); @@ -411,7 +420,6 @@ NodeIterator& NodeIterator::operator++() { return (*this); } - //---------------------------------------- // AncestorIterator Implementation //---------------------------------------- @@ -421,6 +429,23 @@ AncestorIterator& AncestorIterator::operator++() { return (*this); } +//---------------------------------------- +// PathIterator Implementation +//---------------------------------------- + +PathIterator& PathIterator::operator++() { + if (cdest != edest) cdest++; + while (cdest == edest && cnode != enode) { + cnode++; + cdest = cnode->nbegin(); + cdest++; + edest = cnode->nend(); + } + return (*this); +} + + + //---------------------------------------- // istream methods Implementation //---------------------------------------- diff --git a/src/network.hpp b/src/network.hpp index 8a4c6b2..6552cd6 100644 --- a/src/network.hpp +++ b/src/network.hpp @@ -59,6 +59,7 @@ class NetworkLink; class LinkIterator; class NodeIterator; class AncestorIterator; +class PathIterator; class PSLProblem; typedef vector IntList; @@ -266,6 +267,10 @@ class FacilityNode { AncestorIterator abegin(); AncestorIterator aend(); + //For PathIterator + PathIterator pbegin(); + PathIterator pend(); + private: unsigned int id; FacilityType* type; @@ -480,6 +485,65 @@ class AncestorIterator : public std::iterator > { +public: + PathIterator(FacilityNode* p) : cnode(p->nbegin()), enode(p->nend()), cdest(p->nbegin()), edest(p->nend()) { + cdest++; + } + + //Destructor of PathIterator + //Do not delete pointers of iterator + // + ~PathIterator() {} + + PathIterator(const PathIterator& other) : cnode(other.cnode), enode(other.enode), cdest(other.cdest), edest(other.edest) {} + + // The assignment and relational operators are straightforward + PathIterator& operator=(const PathIterator& other) { + if(*this != other) { + cnode= other.cnode; + enode= other.enode; + cdest = other.cdest; + edest = other.edest; + } + return *this; + } + + bool operator==(const PathIterator& other) { + return (cnode == other.cnode) && (cdest== other.cdest); + } + + bool operator!=(const PathIterator& other) { + return (cnode != other.cnode) || (cdest!= other.cdest); + } + + PathIterator& operator++(); + + PathIterator& operator++(int) { + ++(*this); + return *this; + } + + pair operator*() { + return pair(*cnode, *cdest); + } + + pair operator->() { + return *(*this); + } + +private: + NodeIterator cnode; + NodeIterator enode; + NodeIterator cdest; + NodeIterator edest; + }; //---------------------------------------- // PSLProblem Declaration diff --git a/test/main.cpp b/test/main.cpp index 23ebe2a..604d012 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -172,20 +172,30 @@ BOOST_AUTO_TEST_CASE(NetworkIterators) BOOST_CHECK(itA->getID() == itA_copy->getID()); //Count ancestors - int count_ancestors = 0; + int count = 0; for( AncestorIterator i = problem->getRoot()->getChild(0)->getChild(0)->abegin();i != problem->getRoot()->getChild(0)->getChild(0)->aend();i++) { - cout << **i << endl; - count_ancestors++; + count++; } - BOOST_CHECK(count_ancestors == 2); + BOOST_CHECK(count == 2); //Count root ancestors - count_ancestors = 0; + count = 0; for( AncestorIterator i = problem->getRoot()->abegin();i != problem->getRoot()->aend();i++) { - count_ancestors++; + count++; } - BOOST_CHECK(count_ancestors == 0); + BOOST_CHECK(count == 0); + + ///////////////////////////////////////////////// + // UnitTest PathIterator + //////////////////////////////////////////////// + //Count paths + count = 0; + for( PathIterator i = problem->getRoot()->pbegin();i != problem->getRoot()->pend();i++) { + // cout << *(*i).first << " -> "<< *(*i).second << endl; + count++; + } + BOOST_CHECK(count == problem->pathCount()); } BOOST_AUTO_TEST_CASE(networkGeneration)