Click here to Skip to main content
15,885,365 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.
//Trace.h
// Debug tracing functions
#pragma once
#pragma message( "Compiling " __FILE__ ) 

namespace GE_{ namespace dbg {

	//////////////////////////////////////////////////////////////
	// class tracer
	//	provides a mean to send formatted text to the debugger output.
	//	messages can be filtered (to reduce  output verbosity)
	//	and are indented based on the number of tracer object present on the stack

	class tracer
	{
	public:
		//construct with a given filter value
		tracer(int filter);

		//cleanup / destroy
		~tracer();

		//output the parameters based on format
		void operator()(const TCHAR* format, ...);

		//constrict and immediatly prompt
		tracer(int filter, const TCHAR* format, ...) ;

		//get / set the Global filter level.
		static int& filter();

	private:
		struct s_data
		{
			int _filter; //the level of filtering
			int _deep; //the reached deep
			int _count; //the trace main counter
			s_data(): _filter(0),_deep(0)
			{	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );  }
		};
		static s_data& _s() { static s_data s; return s; } //instantiate globally
		int _filter;	//the filter level for this object
		int _cnt; //the countier value for this object

		//initialize the object
		void _init(int filter) 
		{ _filter = filter; _s()._deep++; _cnt = ++_s()._count; }

		//output to the debugger, format using win32 wsprintf series
		void _rpt(const TCHAR* format, va_list arglist)
		{
#ifdef _DEBUG
			if(_filter < filter()) return;
			TCHAR s[1024]; memset(s,0,sizeof(s));
			int m = _stprintf(&s[0], "(%3u)", _filter);
			memset(&s[m],'.',sizeof(TCHAR)*_s()._deep);
			_vstprintf(&s[_s()._deep+m], format, arglist);
			_RPT0(_CRT_WARN, &s[0]);
#endif
		}
	};



	//// inline implementations

	inline tracer::tracer(int filter) 
	{ _init(filter); }

	inline tracer::~tracer() 
	{ _s()._deep--; }

	inline void tracer::operator()(const TCHAR* format, ...)
	{ va_list params; _rpt(format, va_start(params, format)); }

	inline tracer::tracer(int filter, const TCHAR* format, ...)
	{ va_list params; _init(filter); _rpt(format, va_start(params, format)); }

	inline int& tracer::filter() 
	{ return _s()._filter; }


}}

//shortcut macros
// usage:
//		STRACE(trc,1,("format string with a paral = %d \n", paramvalue));
//		SRETRACE(trc,("another string %p \n", a_pointer));

#ifdef _DEBUG
#define STRACE(variable,lev,command) GE_::dbg::tracer variable(lev); variable command;
#define SRETRACE(variable,command) variable command;
#else
#define STRACE(variable,lev,command) //EMPTY
#define SRETRACE(variable,command) //EMPTY
#endif

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