// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include <hash_map>
#include <list>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <Windows.h>
#include <locale.h>
#include <math.h>
#include <boost/bind.hpp>
#include <boost/pool/pool_alloc.hpp>

using namespace std;

class create_counterTag{};

class create_counter
{
	static long cc;
public:
	static long GetCount(){ return cc;}
	static void Reset(){ cc = 0;}
	create_counter(){ ++cc;}
	create_counter(const create_counter&){++cc;}
	/*
	inline static void* operator new(size_t);
	inline static void* operator new(size_t,void*) throw();

	inline static void operator delete(void*);
	//inline static void operator delete[](void*);

	// */

};
/*
typedef boost::singleton_pool<create_counterTag, sizeof(create_counter)> counterPool;

inline void* create_counter::operator new(size_t)
{
	void * p = counterPool::malloc();
	if (p == NULL)
		throw std::bad_alloc();
	return p;
}

inline void create_counter::operator delete(void* p)
{
	if (p != NULL)
		counterPool::free(p);
}

inline void* create_counter::operator new(size_t, void* p)
{
	return ::new(p) create_counter();
}
//*/
long create_counter::cc = 0;

int _tmain(int argc, _TCHAR* argv[])
{
	typedef std::list<create_counter> list_std_cont;
	typedef std::list<create_counter*> list_std_pcont;
	typedef std::list<create_counter, boost::fast_pool_allocator<create_counter> > list_pool_cont;
	typedef std::list<create_counter*, boost::fast_pool_allocator<create_counter*> > list_pool_pcont;
	list_std_cont cont_std;
	list_std_pcont pcont_std;
	list_pool_cont cont_pool;
	list_pool_pcont pcont_pool;

	long totalCount = 1E6;

	for (int j=0;j<2;++j)
	{
		long tBegin = GetTickCount();
		for (int i=0;i<totalCount;++i)
			cont_std.push_back(create_counter());
		long tEnd = GetTickCount();
		cout << "create_counter(list std_allocator) Time: " 
			<< tEnd - tBegin << " Insertions: "
			<< totalCount << " Constations: " 
			<< create_counter::GetCount() << "\n";

		create_counter::Reset();

		tBegin = GetTickCount();
		for (int i=0;i<totalCount;++i)
			pcont_std.push_back(new create_counter);
		tEnd = GetTickCount();
		cout << "create_counter*(list std_allocator) Time: " 
			<< tEnd - tBegin << " Insertions: "
			<< totalCount << " Constations: " 
			<< create_counter::GetCount() << "\n";

		create_counter::Reset();

		tBegin = GetTickCount();
		for (int i=0;i<totalCount;++i)
			cont_pool.push_back(create_counter());
		tEnd = GetTickCount();
		cout << "create_counter(list pool_allocator) Time: " 
			<< tEnd - tBegin << " Insertions: "
			<< totalCount << " Constations: " 
			<< create_counter::GetCount() << "\n";

		create_counter::Reset();

		tBegin = GetTickCount();
		for (int i=0;i<totalCount;++i)
			pcont_pool.push_back(new create_counter);
		tEnd = GetTickCount();
		cout << "create_counter*(list pool_allocator) Time: " 
			<< tEnd - tBegin << " Insertions: "
			<< totalCount << " Constations: " 
			<< create_counter::GetCount() << "\n";

		create_counter::Reset();
		for (list_std_pcont::iterator it=pcont_std.begin(),it_end=pcont_std.end();it != it_end; ++it)
			delete *it;
		for (list_pool_pcont::iterator it=pcont_pool.begin(),it_end=pcont_pool.end();it != it_end; ++it)
			delete *it;

		cont_std.clear();
		pcont_std.clear();
		cont_pool.clear();
		pcont_pool.clear();

		cout << "Clear Data ...\n";
	}

	return 0;
}

