#include <vector>
#include <list>
#include <iostream>

#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>

#define __WIN32__
#include <boost/pool/object_pool.hpp>
#include <boost/pool/pool_alloc.hpp>


using namespace std;

namespace boost {


class RefCount  {
private:
    int crefs;
protected:
    void upcount(void) { 
		++crefs;
	}
    void downcount(void)
    {
		if (--crefs == 0) delete this;
    }

public:
    RefCount(void) { crefs = 0; }
    virtual ~RefCount() {}

	friend void intrusive_ptr_add_ref(RefCount *p);
	friend void intrusive_ptr_release(RefCount *p);
};

inline void intrusive_ptr_add_ref(RefCount *p){
	p->upcount();
}

inline void intrusive_ptr_release(RefCount *p){
	p->downcount();
}


template <class T>
class PoolAllocatedA {
protected:
	object_pool<T> *pc;

public:
	
	void *operator new(size_t n, object_pool<T> *pc_){
		cout << "calling malloc" << endl;
		T *p = pc_->malloc();
		p->pc = pc_;
		return p;
	}

	void operator delete(void *p){
		cout << "calling free" << endl;
		((T *)p)->pc->free((T *)p);
	}

	void operator delete(void *p, object_pool<T> *pc_){
		cout << "calling free ext" << endl;
		pc_->free((T *)p);
	}

};



class PoolAllocatedB {
protected:
	pool<> *pc;

public:
	
	void *operator new(size_t n, pool<> *pc_){
		cout << "calling malloc" << endl;
		PoolAllocatedB *p = (PoolAllocatedB *)pc_->malloc();
		p->pc = pc_;
		return p;
	}

	void operator delete(void *p){
		cout << "calling free" << endl;
		((PoolAllocatedB *)p)->pc->free((PoolAllocatedB *)p);
	}

	void operator delete(void *p, pool<> *pc_){
		cout << "calling free ext" << endl;
		pc_->free((PoolAllocatedB *)p);
	}

};

} //end namespace boost


class c
{
	int i;

public:
	c(int i_){
		cout << "created a new c " << i_ << endl;
		i=i_;
	}
	c() {
		cout << "created a new c " << 0 << endl;
		i=0;
	}
	c(const c &other) : i(other.i) {
		cout << "created a new c " << i << endl;
	}

	virtual ~c(){
		cout << "deleting c " << i << endl;
	}

};


class cRC : public c, 
			public boost::RefCount, 
//			public boost::PoolAllocatedA<cRC>
			public boost::PoolAllocatedB
{
public:
	cRC(int i) : c(i) {}
	cRC(): c() {}
};


typedef boost::intrusive_ptr<cRC> PtrC;


typedef vector<PtrC> LISTC;


void main(){

	LISTC l;

	//boost::object_pool<cRC> a;
	boost::pool<> a(sizeof(cRC));
	
	PtrC p1(new(&a) cRC(1));
	PtrC p2(new(&a) cRC(2));	
	p2=p1;
	PtrC p3(p2);

	if(p1==p3) cout << "equal 1" << endl;
	p2 = NULL;
	if(p1==p2) cout << "equal 2" << endl;
	
	for(int i=0; i< 3;i++){
		PtrC p(new(&a) cRC(i));
		l.push_back(p);
	}

	l.pop_back();

}