Click here to Skip to main content
15,885,767 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.1K   274   30  
Reference counting smart pointers and handles of various flavours.
/////////////////////////////////
// graphs.hpp
//	generic graphs objects
//

#pragma once
#include "compounds.hpp"
#pragma message ("Compiling " __FILE__)


//arcs exists only between nodes

namespace GE_{ namespace stdx{ namespace graph {

	template<class Derived, class Node, class comp_traits>
	class arc;


	template<class Derived, class Arc, class comp_traits=comp_smart_traits>
	class node:
		public comp_traits::base
	{
	public:
		typedef comp_traits traits_t;
		typedef node node_t;
		typedef typename comp_traits::types<Derived>::value Node_t;
		typedef typename comp_traits::types<Derived>::ptr Node_p;
		typedef typename comp_traits::types<Derived>::wptr Node_wp;
		typedef typename comp_traits::types<Arc>::value Arc_t;
		typedef typename comp_traits::types<Arc>::ptr Arc_p;
		typedef typename comp_traits::types<Arc>::wptr Arc_wp;

	private:
		typedef std::list<Arc_p> Arclist_t;
		Arclist_t arcfrom, arcto;
        friend class arc;

	public:
		typedef derefiterator<typename Arclist_t::iterator, Arc&> arc_iterator;
		arc_iterator begin_arcfrom() { return arcfrom.begin(); }
		arc_iterator end_arcfrom() { return arcfrom.end(); }
		arc_iterator begin_arcto() { return arcto.begin(); }
		arc_iterator end_arcto()  { return arcto.end(); }

		void clear_incoming_arcs()
		{
			while(arcfrom.size()!=0)
				arcfrom.front()->unlink();
		}
		void clear_outgoing_arcs()
		{
			while(arcto.size()!=0)
				arcto.front()->unlink();
		}

	protected:

		
		//virtual in case of smart traits, alled automatillally.
		//for dumb traits, call it in the Derived destructor
		void on_lastrelease() 
		{
			clear_incoming_arcs();
			clear_outgoing_arcs();
		}
	};

	
	template<class Derived, class Node, class comp_traits=comp_smart_traits>
	class arc:
		public comp_traits::base
	{
	public:
		typedef comp_traits traits_t;
		typedef arc arc_t;
		typedef typename comp_traits::types<Derived>::value  Arc_t;
		typedef typename comp_traits::types<Derived>::ptr Arc_p;
		typedef typename comp_traits::types<Derived>::wptr Arc_wp;
		typedef typename comp_traits::types<Node>::value Node_t;
		typedef typename comp_traits::types<Node>::ptr Node_p;
		typedef typename comp_traits::types<Node>::wptr Node_wp;

	private:
		Node_wp nodefrom, nodeto;

	public:
		const Node_wp& get_from() const { return nodefrom; }
		const Node_wp& get_to() const { return nodeto; }
		void unlink()
		{
			Arc_p keep(static_cast<Derived*>(this));
			if(nodefrom) 
				nodefrom->arcto.remove(keep);
			if(nodeto) 
				nodeto->arcfrom.remove(keep);
			nodeto=0;
			nodefrom=0;
		}
		void link(const Node_wp& pFrom, const Node_wp& pTo)
		{
			Arc_p keep(static_cast<Derived*>(this));
			unlink();
			pFrom->arcto.push_front(keep);
			pTo->arcfrom.push_front(keep);
			nodefrom = pFrom; nodeto = pTo;
		}
	};

}}}

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