64,648
社区成员
发帖
与我相关
我的任务
分享
template <typename T>
class lazy_alloc : public std::allocator<T>
{
public:
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::size_type size_type;
~lazy_alloc()
{
typedef
typename std::map<size_type, std::stack<pointer> >::iterator
map_iter;
map_iter beg = pool.begin(), end = pool.end();
while (beg != end) {
std::stack<pointer> &store = beg -> second;
while (!store.empty()) {
std::allocator<T>::deallocate(store.top(), beg -> first);
store.pop();
}
++beg;
}
}
pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0)
{
std::stack<pointer> &store = pool[n];
if (store.empty())
return std::allocator<T>::allocate(n, hint);
pointer p = store.top();
store.pop();
return p;
}
void deallocate(pointer p, size_type n)
{
pool[n].push(p);
}
private:
std::map<size_type, std::stack<pointer> > pool;
};
// main.cpp
#include "lazy_alloc.hpp"
#include <cassert>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
#include <list>
using namespace std;
int main(int argc, char *argv[])
{
assert(sizeof(int) == sizeof(float));
#ifndef N
int n = 10;
#else
int n = N;
#endif // N
#ifndef STD
list<int, lazy_alloc<int> > l1;
#else
list<int> l1;
#endif // STD
for (int i = 0; i < n; ++i)
l1.push_back(i);
l1.remove_if(bind2nd(modulus<int>(), 2));
#ifndef STD
list<float, lazy_alloc<float> > l2;
#else
list<float> l2;
#endif // STD
for (int i = 0; i < n; ++i )
l2.push_back(i + 0.1F);
#ifdef OUTPUT
copy(l1.begin(), l1.end(), ostream_iterator<int>(cout, " "));
cout << endl;
copy(l2.begin(), l2.end(), ostream_iterator<float>(cout, " "));
#endif // OUTPUT
cout << endl;
}
// lazy_alloc.hpp
#ifndef LAZH_ALLOC_HPP
#define LAZH_ALLOC_HPP
#include <limits>
#include <map>
#include <stack>
class lazy_alloc_base
{
class pool_t // class for RAII
{
public:
~pool_t()
{
typedef
std::map<size_t, std::stack<void *> >::iterator
map_iter;
map_iter beg = cache.begin(), end = cache.end();
while (beg != end) {
std::stack<void *> &store = beg -> second;
while (! store.empty()) {
operator delete(store.top());
store.pop();
}
++beg;
}
}
std::stack<void *> & operator[](const size_t &n)
{
return cache[n];
}
private:
std::map<size_t, std::stack<void *> > cache;
};
protected:
static pool_t pool;
};
lazy_alloc_base::pool_t lazy_alloc_base::pool;
template <typename T>
class lazy_alloc;
template <>
class lazy_alloc<void>
{
public:
typedef void * pointer;
typedef const void * const_pointer;
typedef void value_type;
template <typename U>
struct rebind { typedef lazy_alloc<U> other; };
};
template <typename T>
class lazy_alloc : public lazy_alloc_base // now any instance of type lazy_alloc will be sharing the same pool
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef T & reference;
typedef const T & const_reference;
typedef T value_type;
template <typename U>
struct rebind { typedef lazy_alloc<U> other; };
pointer address(reference value) const
{
return &value;
}
const_pointer address(const_reference value) const
{
return &value;
}
lazy_alloc() throw ()
{ }
lazy_alloc(const lazy_alloc &) throw ()
{ }
template <typename U>
lazy_alloc(const lazy_alloc<U> &) throw ()
{ }
~lazy_alloc() throw ()
{ }
size_type max_size() const throw ()
{
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
void construct(pointer p, const value_type &value)
{
new(p)value_type(value);
}
void destroy(pointer p)
{
p -> ~T();
}
pointer allocate(size_type n, lazy_alloc<void>::const_pointer hint = 0)
{
std::stack<void *> &store = pool[n];
if (store.empty())
return (pointer)operator new(sizeof(n * sizeof(value_type)));
pointer p = (pointer)store.top();
store.pop();
return p;
}
void deallocate(pointer p, size_type n)
{
pool[n].push(p);
}
};
template <typename T, typename U>
bool operator==(const lazy_alloc<T> &, const lazy_alloc<U> &) throw ()
{ return true; }
template <typename T, typename U>
bool operator!=(const lazy_alloc<T> &, const lazy_alloc<U> &) throw ()
{ return false; }
#endif // LAZH_ALLOC_HPP