Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A policy based reference counting implementation for compound objects

, 26 May 2005 CPOL
Reference counting smart pointers and handles of various flavours.
/////////////////////////
//	c0.cpp

#include "stdafx.h"

#include "stdx/msgrouter.hpp"

/// stdx::smart testing
//	run in debug mode an read messagess on the output window

using namespace GE_;

//struct A and C are nodes and arcs of a graph


struct C; //forwarded

struct A: //A is a graph node and also a hierarchy node
	public stdx::graph::node<A, C>, 
	public stdx::hierarchy_node<A>
{
	int a; //an ID
	A() 
	{ 
		static int n(0); a = ++n;  //count and save
		STRACE(trc, 1, ("Created A #%d at %p\n", a, this));
	}
	virtual ~A() 
	{	STRACE(trc, 1, ("Deleted A #%d at %p\n", a, this)); }

	void on_data(int& i) 
	{ 
		STRACE(t,1,("Broadcasting %d to Node #%d\n", i, a));
	}

protected:
	void on_lastrelease() //disambiguate
	{
		stdx::graph::node<A, C>::on_lastrelease();
		stdx::hierarchy_node<A>::on_lastrelease();
	}
};

struct B: public A
{
	B() { a += 100; } //B will have 100+xx as ID
};


struct C:
	stdx::graph::arc<C, A>
{
	int c;
	C()
	{
		static int n(0); c = ++n; //same trick as for A
		STRACE(t,1,("Creating C #%d at %p\n",c,this));
	}
	virtual ~C()
	{	STRACE(t,1,("Deleting C #%d at %p\n",c,this)); }

};


int main()
{
	STRACE(trc, 0, ("c0 main\n"));
	
	static const int n=25;
	A::ptr pA; pA.New(); //the capostipit for everything
	
	for(size_t i=0; i<n; i++) 
	{
		//place n nodes into the capostipit. One B every three A
		if(! (i%4))
		{	B* p; stdx::New(p); pA->set_last(p); }
		else
		{	A* p; stdx::New(p); pA->set_last(p); }
	}
	
	for(i=0;i<n*2;i++) 
	{
		int m = n-1;
		C::Arc_p p; p.New(); //create an arc
		int frm = rand()*m/RAND_MAX;  //generate two random numbers from 0 to n-1
		int to = rand()*m/RAND_MAX;
		p->link(pA->get_child(frm), pA->get_child(to)); //link the nodes having that indexes
	}
	

	//do a simple graph visit
	for(A::ptr pN = pA->get_first(); pN; pN = pN->get_next()) 
	{//loop all the nodes
		for(A::arc_iterator a=pN->begin_arcto(); a!=pN->end_arcto(); a++)
		{//loop all outgoing arcs
			A::ptr pTo = a->get_to(); //get arc destination
			int idfrom = pN->a; //node ID
			int idto = (pTo)? pTo->a: 0; //destination ID
			int idarc = a->c; //arc ID
			STRACE(t,2,("Node #%d, linked to Node #%d by Arc #%d\n", idfrom,idto,idarc));
		}
	}

	//try broadcasting from the first node
	int count(0); A* pa(pA->get_first());
	for(; pa; pa=pa->get_next())
	{
		STRACE(t,1,("BackBroadcast from #%d\n", pa->a));
		stdx::graph::backroute_linked(++count, *pa, std::mem_fun(&A::on_data));
		SRETRACE(t,("Broadcast from #%d\n", pa->a));
		stdx::graph::route_linked(count, *pa, std::mem_fun(&A::on_data));
	}

	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Emilio Garavaglia
Architect
Italy Italy
Born and living in Milan (Italy), I'm an engineer in electronics actually working in the ICT department of an important oil/gas & energy company as responsible for planning and engineering of ICT infrastructures.
Interested in programming since the '70s, today I still define architectures for the ICT, deploying dedicated specific client application for engineering purposes, working with C++, MFC, STL, and recently also C# and D.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141220.1 | Last Updated 27 May 2005
Article Copyright 2005 by Emilio Garavaglia
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid