Click here to Skip to main content
15,896,111 members
Articles / Programming Languages / C++

A policy based reference counting implementation for compound objects

Rate me:
Please Sign up or sign in to vote.
4.77/5 (13 votes)
26 May 2005CPOL16 min read 33.3K   274   30  
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)


Written By
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.

Comments and Discussions