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.
////////////////////////////////////////////////
//	helpers0.h
//		helper function and classes
//


#pragma once
#pragma message("Compiling " __FILE__)

namespace GE_{ namespace stdx {


	//temporarilly assign a value
	template<class A>
	class temp_assign
	{
	private:
		A old;
		A& v;
	public:
		
		temp_assign(A& var, const A& val)
			:v(var)
		{	old = var; var = val; }
		
		~temp_assign()
		{	v = old; }
	};

	

	template<class excp>
		void throw_excpptr() { static excp e; throw &e; }

	
	//geneates numbers in sequnence from a given start
	namespace ID_
	{
		template<class policy>
		struct gen:
			public policy
		{
			static unsigned get_ID() //a many series as needed
			{	static unsigned n(get_start()); return ++n; }
		};

		struct cmd_policy
		{	static unsigned get_start() { return 32768;	} };

		struct ctrlID_policy
		{	static unsigned get_start() { return 100;	} };

		struct typednotify_policy
		{	static unsigned get_start() { return 4000;	} };

		struct type_policy
		{	static unsigned get_start() { return 8000;	} };

		struct enum_policy
		{	static unsigned get_start() { return 65536;	} };
	}

	struct IDGen
	{
		typedef ID_::gen<ID_::cmd_policy> cmd;
		typedef ID_::gen<ID_::ctrlID_policy> ctrlId;
		typedef ID_::gen<ID_::typednotify_policy> typednotify;
		typedef ID_::gen<ID_::type_policy> typeId;
		typedef ID_::gen<ID_::enum_policy> enumeral;
	};
	
	//associate an ID to a type
	template<class Type>
		unsigned type_to_ID() { static unsigned n(IDGen::typeId::get_ID()); return n; }


	//OOP predicate
	template<class param>
	class predicate
	{
	protected:
		virtual bool is(const param& p) {return false;}
	public:
		bool operator()(const param& p) { return is(p); }
	};

	
	//search inside an array
	template<class Type>
	Type* seek_array(const Type& val, Type* v0, int nCount)
	{
		for(int i=0; i<nCount; i++)
			if((&v0)[i] == val)
				return &(v0)[i];
		return 0;
	}

	//seek into an std::map without create
	template<class Map>
		typename Map::mapped_type* search_map(Map& m, typename Map::key_type& k)
	{
		typename Map::iterator i = m.find(k);
		return (i == m.end())? 0: &i->second;
	}

	//sigleton
	template<class Type>
	class global
	{
	public:
		Type& operator()() const { return g_(); }
		operator Type&() const { return g_(); }
	private:
		static Type& g_() { static Type t; return t; }
	};



	template<class Derived>
	struct operators
	{
		template<class Right>
			Derived operator+(const Right& r) const { return Derived(static_cast<const Derived&>(*this))+=r; }
		template<class Right>
			Derived operator-(const Right& r) const { return Derived(static_cast<const Derived&>(*this))-=r; }
		template<class Right>
			Derived operator*(const Right& r) const { return Derived(static_cast<const Derived&>(*this))*=r; }
		template<class Right>
			Derived operator/(const Right& r) const { return Derived(static_cast<const Derived&>(*this))/=r; }
		template<class Right>
			Derived operator&(const Right& r) const { return Derived(static_cast<const Derived&>(*this))+=r; }
		template<class Right>
			Derived operator|(const Right& r) const { return Derived(static_cast<const Derived&>(*this))+=r; }
		template<class Right>
			Derived operator^(const Right& r) const { return Derived(static_cast<const Derived&>(*this))+=r; }
		template<class Right>
			bool operator!=(const Right& r) const { const Derived& l(static_cast<const Derived&>(*this)); return !(l==r); }
		template<class Right>
			bool operator<=(const Right& r) const { const Derived& l(static_cast<const Derived&>(*this)); return (l<r !! l==r);  }
		template<class Right>
			bool operator>=(const Right& r) const { const Derived& l(static_cast<const Derived&>(*this)); return !(l<r);  }
		template<class Right>
			bool operator>(const Right& r) const { const Derived& l(static_cast<const Derived&>(*this)); return !(l<=r);  }
	};


	//new / delete shortcuts
	// note Type must be a pointer equivalent type

	template<class Type> 
		void New(Type*& p) { p = new Type(); }
	template<class Type, class A>
		Type* New(Type*& p, const A& a) { return p = new Type(a); }
	template<class Type, class A, class B>
		Type* New(Type*& p, const A& a, const B& b) { return p = new Type(a,b); }
	template<class Type>
		void Delete(Type*& p) { delete &*p; p=0; }


	template<class Iter, class Deref>
	struct derefiterator:
		public Iter
	{
		derefiterator() 
		{}
		derefiterator(const derefiterator& i)
			:Iter((const Iter&)i) 
		{}
		derefiterator(const Iter& i)
			:Iter(i)
		{}

		typedef Deref reference;
		typedef typename Iter::value_type pointer;

		typename Iter::value_type operator->() { return Iter::operator*(); }
		Deref operator*() { return *Iter::operator*(); }
	};

}}


namespace GE_ { namespace operators {


	//various operator:
	// NOTE: you must have GE_::operators namespace in your scope to call them !

    template<class A, class B>
		A operator+(const A& a, const B& b) { A tmp(a); tmp+=b; return tmp; }

    template<class A, class B>
		A operator-(const A& a, const B& b) { A tmp(a); tmp-=b; return tmp; }

    template<class A, class B>
		A operator*(const A& a, const B& b) { A tmp(a); tmp*=b; return tmp; }

    template<class A, class B>
		A operator/(const A& a, const B& b) { A tmp(a); tmp/=b; return tmp; }

    template<class A, class B>
		A operator&(const A& a, const B& b) { A tmp(a); tmp&=b; return tmp; }

    template<class A, class B>
		A operator|(const A& a, const B& b) { A tmp(a); tmp|=b; return tmp; }

    template<class A, class B>
		A operator^(const A& a, const B& b) { A tmp(a); tmp^=b; return tmp; }

    template<class A, class B>
		bool operator!=(const A& a, const B& b) { return !(a==b); }
	
    template<class A, class B>
		bool operator<=(const A& a, const B& b) { return (a<b)||(a==b); }
	
    template<class A, class B>
		bool operator>(const A& a, const B& b) { return (b<a); }
	
    template<class A, class B>
		bool operator>=(const A& a, const B& b) { return (b<=a); }
	
	//provides frequent compare-and-assign operations

	//set A to stay less than a given maximum
	template<class A, class B>
		bool set_max(A& a, const B& b)
	{	if(b<a) { a=b; return true; } return false; }

	
	//set A to stay more than a given minimum
	template<class A, class B>
		bool set_min(A& a, const B& b)
	{	if(a<b) { a=b; return true; } return false; }

	//set A to stay in a given range
	template<class A, class B, class C>
		bool set_range(A&a, const B& _min, const C& _max)
	{	bool b1 = set_min(a,_min); bool b2 = set_max(a,_max); return b1||b2; }


	//get the max & min
	template<class A>
		A Max(const A& a, const A& b)
	{	return (a<b)? b: a; }

	template<class A>
		A Min(const A& a, const A& b)
	{	return (b<a)? b: a; }


}}

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
Web04 | 2.8.150327.1 | Last Updated 27 May 2005
Article Copyright 2005 by Emilio Garavaglia
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid