#include <vector>
#include <string>
#include <list>
#include <iostream>
#include <ctime>
#include <atlcoll.h>
#include <memory>
static const int test_count = 1000000;
class impl {
public:
template<class T> T* allocate(unsigned n, const T* hint, std::allocator<T>* al) {if (e-c>=n) {char* t(c); c+=n; return (T*)t;}return al->allocate(n, hint);}
template<class T> void deallocate(T* p, unsigned n, std::allocator<T>* al) {if ((char*)p<(char*)this || (char*)p>e) al->deallocate(p, n);}
static impl* construct(int size) {return new(new char[size+sizeof(impl)])impl(size); }
void inc_ref_count() {++p;}
void dec_ref_count() { if (--p == 0) {this->~impl(); delete[]((char*)this);}}
private:
char* c;
char* e;
int p;
impl(int size): c(((char*)this)+sizeof(impl)), e(c+size), p(1){}
impl(impl& nocopy);
impl&operator=(impl& nocopy);
};
template<class T>
class pool_allocator : public std::allocator<T> {
impl* al;
public:
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::const_pointer const_pointer;
template<class U> struct rebind {typedef pool_allocator<U> other;};
template<class U> friend class pool_allocator;
pool_allocator() : std::allocator<T>(), al(impl::construct(4096)) {}
explicit pool_allocator(unsigned size) : std::allocator<T>(), al(impl::construct(size)) {}
pool_allocator(const pool_allocator& rhs) : std::allocator<T>(rhs), al(rhs.al) {al->inc_ref_count();}
template<class U> pool_allocator(const pool_allocator<U>& rhs) : std::allocator<T>(rhs), al(rhs.al) {al->inc_ref_count();}
~pool_allocator() {al->dec_ref_count();}
pointer allocate(size_type n, const_pointer hint = 0 ) {return al->allocate<T>(n*sizeof(T), hint, this);}
void deallocate(pointer p, size_type n) {al->deallocate<T>(p, n*sizeof(T), this);}
pool_allocator& operator=(const pool_allocator& rhs) {std::allocator<T>::operator=(rhs); al->dec_ref_count(); al=rhs.al; al->inc_ref_count();}
template<class U> pool_allocator& operator=(const pool_allocator<U>& rhs) {std::allocator<T>::operator=(rhs); al->dec_ref_count(); al=rhs.al; al->inc_ref_count();}
};
void list_stl()
{
pool_allocator<double> alloc(test_count*12);
std::list<double/*, pool_allocator<double>*/> items/*(alloc)*/;
std::cout << "10M doubles in std::list ";
clock_t begin = clock();
for( int i = 0; i < test_count; i++ )
items.push_back( rand() );
std::cout << (double(clock()-begin)/CLOCKS_PER_SEC) << '\n';
}
void list_atl()
{
CAtlList<double> items;
std::cout << "10M doubles in CAtlList " ;
clock_t begin = clock();
for( int i = 0; i < test_count; i++ )
items.AddTail( rand() );
std::cout << (double(clock()-begin)/CLOCKS_PER_SEC) << '\n';
}
int main() {
list_stl();
list_stl();
list_atl();
list_atl();
return 0;
}
/*
10M doubles in std::list 0.453
10M doubles in std::list 0.453
10M doubles in CAtlList 0.188
10M doubles in CAtlList 0.187
10M doubles in std::list 1.328
10M doubles in std::list 1.359
10M doubles in CAtlList 0.188
10M doubles in CAtlList 0.172
*/