A
Aryeh M. Friedman
Why is the value of "Instance" whacked in the following code. Note this
only happens in Graph::*Wrapper.
Also please note that if I hardcode WalkFunc and PrintFunct to be
BredthFirst and BredthFirstPrint and make both approriate func ptrs it works
fine.
void print(void *data);
#define R 'r'-'r'
#define S 's'-'r'
#define T 't'-'r'
#define U 'u'-'r'
#define V 'v'-'r'
#define W 'w'-'r'
#define X 'x'-'r'
#define Y 'y'-'r'
int main()
{
int i;
Graph *graph;
char *s="rstuvwxy";
graph=graph->init();
for(i=0;i<8;i++)
graph->addNode(&s);
graph->addEdge(&s[R],&s);
graph->addEdge(&s[R],&s[V]);
graph->addEdge(&s,&s[W]);
graph->addEdge(&s[W],&s);
graph->addEdge(&s[W],&s[T]);
graph->addEdge(&s[T],&s[X]);
graph->addEdge(&s[T],&s);
graph->addEdge(&s,&s[Y]);
graph->addEdge(&s[X],&s[Y]);
graph->walk();
graph->print(print,&s[R],&s[Y]);
}
void print(void *data)
{
cout<<*RI_CAST<char *>(data)<<endl;
}
class Graph {
public:
Graph *init(unsigned long walkfunc=0,unsigned long printfunc=0);
void addNode(void *data);
void addEdge(void *d1, void *d2);
GNode *findNode(void *data);
void walk();
void print(void (*func)(void *data),void *d1,void *d2);
static void BredthFirstWrapper();
static void
BredthFirstPrintWrapper(void (*func)(void *data),GNode
*node,GNode *node2);
void Dump();
//protected:
Graph(unsigned long walkfunc=0,unsigned long printfunc=0);
private:
void BredthFirst();
void BredthFirstPrint(void (*func)(void *data),GNode *node,GNode
*node2);
void reset();
static Graph *Instance;
LinkedList *Nodes;
unsigned long WalkFunc;
unsigned long PrintFunc;
};
Graph *Graph::Instance=0;
Graph *Graph::init(unsigned long walkfunc,unsigned long printfunc)
{
return new Graph(walkfunc,printfunc);
}
void Graph::addNode(void *data)
{
GNode *node;
node=node->init(data);
Nodes->addNode(node);
}
void Graph::addEdge(void *d1,void *d2)
{
GNode *node;
GNode *node2;
node=findNode(d1);
node2=findNode(d2);
node->addEdge(node2);
node2->addEdge(node);
}
GNode *Graph::findNode(void *data)
{
GNode *node;
Nodes->reset(); // paranoia
while((node=RI_CAST<GNode *>(Nodes->getNext()))!=0)
if(node->getData()==data) {
Nodes->reset();
return node;
}
Nodes->reset();
return 0;
}
void Graph::walk()
{
Instance=this;
(RI_CAST<void (*)(Graph *)>(WalkFunc))(this);
}
void Graph:rint(void (*func)(void *data),void *d1,void *d2)
{
GNode *node;
GNode *node2;
node=findNode(d1);
node2=findNode(d2);
if(node==0||node2==0) {
cout<<"Can't find one of the path ends for this graph print"<<endl;
exit(1);
}
Instance=this;
(RI_CAST<void (*)(Graph *,void (*)(void *),GNode *, GNode *)>(PrintFunc))
(this,func,node,node2);
}
void Graph::BredthFirstWrapper()
{
if(Instance==0)
return;
Instance->BredthFirst();
}
void Graph::BredthFirstPrintWrapper(void (*func)(void *data),GNode
*node,GNode *node2)
{
if(Instance==0)
return;
cout<<node<<" "<<node2<<endl;
Instance->BredthFirstPrint(func,node,node2);
}
void Graph:ump()
{
GNode *node;
cout<<"Nodes: "<<endl;
while((node=RI_CAST<GNode *>(Nodes->getNext()))!=0)
node->Dump();
Nodes->reset();
}
Graph::Graph(unsigned long walkfunc,unsigned long printfunc)
{
Nodes=Nodes->init();
if(walkfunc==0)
walkfunc=RI_CAST<unsigned long>(&Graph::BredthFirstWrapper);
WalkFunc=(walkfunc);
if(printfunc==0)
printfunc=RI_CAST<unsigned long>(&Graph::BredthFirstPrintWrapper);
PrintFunc=printfunc;
}
void Graph::BredthFirst()
{
GNode *node;
GNode *tmp;
Queue *queue;
LinkedList *edges;
reset();
node=RI_CAST<GNode *>(Nodes->getNext());
if(node==0)
return;
node->setColor(GNodeColorGrey);
queue=queue->init();
queue->insert(node);
node->setDepth(0);
node->setPrev(0);
do {
node=RI_CAST<GNode *>(queue->peek());
cout<<"processing node "<<node<<endl;
edges=node->getEdges();
while((tmp=RI_CAST<GNode *>(edges->getNext()))!=0)
if(tmp->getColor()==GNodeColorWhite) {
tmp->setColor(GNodeColorGrey);
tmp->setDepth(node->getDepth()+1);
tmp->setPrev(node);
queue->insert(tmp);
}
edges->reset();
node=RI_CAST<GNode *>(queue->get());
if(node==0)
break;
node->setColor(GNodeColorBlack);
} while(queue->getSize()>0);
}
void Graph::BredthFirstPrint(void (*func)(void *data),GNode *node, GNode
*node2)
{
if(node==node2) {
func(node->getData());
return;
}
if(node2->getPrev()==0) {
cout<<"No path from "<<node<<" to "<<node2<<endl;
exit(1);
}
BredthFirstPrint(func,node,node2->getPrev());
func(node2->getData());
}
void Graph::reset()
{
GNode *node;
while((node=RI_CAST<GNode *>(Nodes->getNext()))!=0)
node->reset();
Nodes->reset();
}
only happens in Graph::*Wrapper.
Also please note that if I hardcode WalkFunc and PrintFunct to be
BredthFirst and BredthFirstPrint and make both approriate func ptrs it works
fine.
void print(void *data);
#define R 'r'-'r'
#define S 's'-'r'
#define T 't'-'r'
#define U 'u'-'r'
#define V 'v'-'r'
#define W 'w'-'r'
#define X 'x'-'r'
#define Y 'y'-'r'
int main()
{
int i;
Graph *graph;
char *s="rstuvwxy";
graph=graph->init();
for(i=0;i<8;i++)
graph->addNode(&s);
graph->addEdge(&s[R],&s
graph->addEdge(&s[R],&s[V]);
graph->addEdge(&s
graph->addEdge(&s[W],&s
graph->addEdge(&s[W],&s[T]);
graph->addEdge(&s[T],&s[X]);
graph->addEdge(&s[T],&s);
graph->addEdge(&s,&s[Y]);
graph->addEdge(&s[X],&s[Y]);
graph->walk();
graph->print(print,&s[R],&s[Y]);
}
void print(void *data)
{
cout<<*RI_CAST<char *>(data)<<endl;
}
class Graph {
public:
Graph *init(unsigned long walkfunc=0,unsigned long printfunc=0);
void addNode(void *data);
void addEdge(void *d1, void *d2);
GNode *findNode(void *data);
void walk();
void print(void (*func)(void *data),void *d1,void *d2);
static void BredthFirstWrapper();
static void
BredthFirstPrintWrapper(void (*func)(void *data),GNode
*node,GNode *node2);
void Dump();
//protected:
Graph(unsigned long walkfunc=0,unsigned long printfunc=0);
private:
void BredthFirst();
void BredthFirstPrint(void (*func)(void *data),GNode *node,GNode
*node2);
void reset();
static Graph *Instance;
LinkedList *Nodes;
unsigned long WalkFunc;
unsigned long PrintFunc;
};
Graph *Graph::Instance=0;
Graph *Graph::init(unsigned long walkfunc,unsigned long printfunc)
{
return new Graph(walkfunc,printfunc);
}
void Graph::addNode(void *data)
{
GNode *node;
node=node->init(data);
Nodes->addNode(node);
}
void Graph::addEdge(void *d1,void *d2)
{
GNode *node;
GNode *node2;
node=findNode(d1);
node2=findNode(d2);
node->addEdge(node2);
node2->addEdge(node);
}
GNode *Graph::findNode(void *data)
{
GNode *node;
Nodes->reset(); // paranoia
while((node=RI_CAST<GNode *>(Nodes->getNext()))!=0)
if(node->getData()==data) {
Nodes->reset();
return node;
}
Nodes->reset();
return 0;
}
void Graph::walk()
{
Instance=this;
(RI_CAST<void (*)(Graph *)>(WalkFunc))(this);
}
void Graph:rint(void (*func)(void *data),void *d1,void *d2)
{
GNode *node;
GNode *node2;
node=findNode(d1);
node2=findNode(d2);
if(node==0||node2==0) {
cout<<"Can't find one of the path ends for this graph print"<<endl;
exit(1);
}
Instance=this;
(RI_CAST<void (*)(Graph *,void (*)(void *),GNode *, GNode *)>(PrintFunc))
(this,func,node,node2);
}
void Graph::BredthFirstWrapper()
{
if(Instance==0)
return;
Instance->BredthFirst();
}
void Graph::BredthFirstPrintWrapper(void (*func)(void *data),GNode
*node,GNode *node2)
{
if(Instance==0)
return;
cout<<node<<" "<<node2<<endl;
Instance->BredthFirstPrint(func,node,node2);
}
void Graph:ump()
{
GNode *node;
cout<<"Nodes: "<<endl;
while((node=RI_CAST<GNode *>(Nodes->getNext()))!=0)
node->Dump();
Nodes->reset();
}
Graph::Graph(unsigned long walkfunc,unsigned long printfunc)
{
Nodes=Nodes->init();
if(walkfunc==0)
walkfunc=RI_CAST<unsigned long>(&Graph::BredthFirstWrapper);
WalkFunc=(walkfunc);
if(printfunc==0)
printfunc=RI_CAST<unsigned long>(&Graph::BredthFirstPrintWrapper);
PrintFunc=printfunc;
}
void Graph::BredthFirst()
{
GNode *node;
GNode *tmp;
Queue *queue;
LinkedList *edges;
reset();
node=RI_CAST<GNode *>(Nodes->getNext());
if(node==0)
return;
node->setColor(GNodeColorGrey);
queue=queue->init();
queue->insert(node);
node->setDepth(0);
node->setPrev(0);
do {
node=RI_CAST<GNode *>(queue->peek());
cout<<"processing node "<<node<<endl;
edges=node->getEdges();
while((tmp=RI_CAST<GNode *>(edges->getNext()))!=0)
if(tmp->getColor()==GNodeColorWhite) {
tmp->setColor(GNodeColorGrey);
tmp->setDepth(node->getDepth()+1);
tmp->setPrev(node);
queue->insert(tmp);
}
edges->reset();
node=RI_CAST<GNode *>(queue->get());
if(node==0)
break;
node->setColor(GNodeColorBlack);
} while(queue->getSize()>0);
}
void Graph::BredthFirstPrint(void (*func)(void *data),GNode *node, GNode
*node2)
{
if(node==node2) {
func(node->getData());
return;
}
if(node2->getPrev()==0) {
cout<<"No path from "<<node<<" to "<<node2<<endl;
exit(1);
}
BredthFirstPrint(func,node,node2->getPrev());
func(node2->getData());
}
void Graph::reset()
{
GNode *node;
while((node=RI_CAST<GNode *>(Nodes->getNext()))!=0)
node->reset();
Nodes->reset();
}