Click here to Skip to main content
15,897,226 members
Articles / Programming Languages / C++

generic_ptr and Its Generator

Rate me:
Please Sign up or sign in to vote.
4.29/5 (4 votes)
9 Mar 2010CPOL5 min read 17.3K   113   9  
Generic object wrapper for delayed type selection
#include "generic_ptr.h"
#include <iostream>
#include <boost/any.hpp>

//dumy audio filter class just test purposes.
template<typename T>
class audio_filter
{
public:
	typedef T sample_t;
public:
	audio_filter()
		: m_gain(0)
		, m_total_samples(0)
		, m_samples_p(NULL)
	{}
	~audio_filter(){}

public:
	void initialize(int _average_sample_count)throw(std::exception)
	{
		std::cout<<"initialize called, sample_t: "<<typeid(sample_t).name()<<std::endl;
		// ...
	}
	void set_gain(sample_t _gain)
	{
		std::cout<<"set_gain called, sample_t: "<<typeid(sample_t).name()<<std::endl;
		m_gain = _gain;
	}
	sample_t get_gain()const
	{
		std::cout<<"get_gain called, sample_t: "<<typeid(sample_t).name()<<std::endl;
		return m_gain;
	}
	const short* process(short* _samples_p, int _sample_count)
	{
		std::cout<<"process called, sample_t: "<<typeid(sample_t).name()<<std::endl;
		//...
		return m_samples_p;
	}
	int get_total_samples()const
	{
		std::cout<<"get_total_samples called, sample_t: "<<typeid(sample_t).name()<<std::endl;
		return m_total_samples;
	}
private:
	sample_t m_gain;
	int m_total_samples;
	short* m_samples_p;
};

GENERIC_PTR
(
 GEN_NAME(audio_info)
 GEN_METHOD_SIG(GEN_RET_NONE() GEN_NAME(initialize) GEN_PARAMS(GEN_TYPE(int)) GEN_THROW_OF(std::exception))
 GEN_METHOD_SIG(GEN_RET_NONE() GEN_NAME(set_gain) GEN_PARAMS(GEN_DEPEND_TYPE(typename T::sample_t)))
 GEN_METHOD_SIG(GEN_RET_DEPEND_TYPE() GEN_NAME(get_gain) GEN_PARAMS_NONE() GEN_TRAILING_CONST())
 GEN_METHOD_SIG(GEN_RET_TYPE(const short*) GEN_NAME(process) GEN_PARAMS(GEN_TYPE(short*) GEN_TYPE(int)))
 GEN_METHOD_SIG(GEN_RET_TYPE(int) GEN_NAME(get_total_samples) GEN_PARAMS_NONE() GEN_TRAILING_CONST())
)

enum precision{low_precision,normal_precision,high_precision};

class audio_manager
{
public:	
	void initialize(precision _precision, int _average_sample_count, double _gain)
	{
		if (_precision == low_precision)
		{
			m_audio_filter_gp.reset(boost::shared_ptr<audio_filter<short> >(new audio_filter<short>()));
		}
		else if (_precision == normal_precision)
		{
			m_audio_filter_gp.reset(boost::shared_ptr<audio_filter<float> >(new audio_filter<float>()));
		}
		else if (_precision == high_precision)
		{
			m_audio_filter_gp.reset(boost::shared_ptr<audio_filter<double> >(new audio_filter<double>()));
		}

		m_audio_filter_gp->initialize(_average_sample_count);

		// for depended types, the parameter type must be the same type as the expected or boost::any_cast 
		// throws an exception
		if (_precision == low_precision)
		{
			m_audio_filter_gp->set_gain(static_cast<short>(_gain));
			short gain = boost::any_cast<short>(m_audio_filter_gp->get_gain());
			std::cout<<"gain is: "<<gain<<std::endl;
		}
		else if (_precision == normal_precision)
		{
			m_audio_filter_gp->set_gain(static_cast<float>(_gain));
			float gain = boost::any_cast<float>(m_audio_filter_gp->get_gain());
			std::cout<<"gain is: "<<gain<<std::endl;
		}
		else if (_precision == high_precision)
		{
			m_audio_filter_gp->set_gain(_gain);
			double gain = boost::any_cast<double>(m_audio_filter_gp->get_gain());
			std::cout<<"gain is: "<<gain<<std::endl;
		}
	}

	void process(short* _samples_p, int _sample_count)
	{
		m_audio_filter_gp->process(_samples_p,_sample_count);
	}

	int total_processed()
	{
		return m_audio_filter_gp->get_total_samples();
	}

private:
	msh_utils::generic_audio_info_ptr_t m_audio_filter_gp;
};

int main (int argc, char* argv[])
{
	short samples[100] = {0};
	audio_manager manager;

	std::cout<<std::endl;

	manager.initialize(low_precision,100,10.3);
	manager.process(samples,100);
	manager.total_processed();

	std::cout<<std::endl<<std::endl;

	manager.initialize(normal_precision,100,10.3);
	manager.process(samples,100);
	manager.total_processed();

	std::cout<<std::endl<<std::endl;

	manager.initialize(high_precision,100,10.3);
	manager.process(samples,100);
	manager.total_processed();

	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
Software Developer Metus Technology
Turkey Turkey
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions