template <class CompositeType, class ProcessType>
int rVisit(CompositeType &cobj, ProcessType &pobj)
{
// "stack" of composite handles
deque<ProcessType::CompositeHandle> cdeq;
// number of composites at current level
deque<int> ndeq;
// temporary vectors of simple and composite handles
vector<ProcessType::SimpleHandle> svec;
vector<ProcessType::CompositeHandle> tempcvec;
int depth = 0;
bool searching = true;
bool done = false;
int count = 0;
while(!done)
{
if(searching)
{
// clear simple and composite handle vectors
svec.erase(svec.begin(), svec.end());
tempcvec.erase(tempcvec.begin(), tempcvec.end());
// get hanles at this level
pobj.getHandles(cobj, tempcvec, svec);
ndeq.push_back(tempcvec.size());
// push CompositeHandles to stack in reverse order
for(int i = tempcvec.size()-1; i >= 0; --i)
cdeq.push_back(tempcvec[i]);
// process elements at this level
for(int i = 0; i < tempcvec.size(); ++i)
{
pobj.processComposite(cobj, tempcvec[i]);
count++;
}
for(int j = 0; j < svec.size(); ++j)
{
pobj.processSimple(cobj, svec[j]);
count++;
}
searching = false;
}
else // in not-searching state
{
if(ndeq.back() > 0) // more unexpanded composites
{ // try to move down a level
pobj.moveDownTo(cobj, cdeq.back());
assert(cdeq.size() > 0);
cdeq.pop_back();
ndeq.back()--;
depth++;
searching = true;
}
else // no more unexpanded composites
{ // try to move back up a level
if(depth > 0) // we can move up
{
assert(ndeq.size() > 0);
ndeq.pop_back();
pobj.moveUp(cobj);
depth--;
}
else // already at top -- we're done
{
assert(ndeq.size() > 0);
ndeq.pop_back();
done = true;
}
}
}
}
assert(ndeq.size() == 0);
assert(cdeq.size() == 0);
assert(depth == 0);
return count;
}