// http://blogs.msdn.com/b/vcblog/archive/2008/08/28/the-mallocator.aspx
template <typename T> class Mallocator;

template <> class Mallocator<void>
{
public:
    typedef void*        pointer;
    typedef const void*  const_pointer;
    // reference to void members are impossible.
    typedef void         value_type;

public:
    template <class U> struct rebind { typedef pool_allocator<U> other; };
};   

template <typename T>
class Mallocator
{
public:
 // The following will be the same for virtually all allocators.
 typedef T*        pointer;
 typedef const T*  const_pointer;
 typedef T&        reference;
 typedef const T&  const_reference;
 typedef T         value_type;
 typedef size_t    size_type;
 typedef ptrdiff_t difference_type;

public:
 // Default constructor, copy constructor, rebinding constructor, and destructor.
 // Empty for stateless allocators.
 Mallocator()
 {
 }

 ~Mallocator()
 {
 }

 Mallocator(const Mallocator&)
 {
 }

public:
 // The following must be the same for all allocators.
 template <typename U> struct rebind { typedef Mallocator<U> other; };
 template <typename U> Mallocator(const Mallocator<U>&) {}

 // Returns true if and only if storage allocated from *this
 // can be deallocated from other, and vice versa.
 // Always returns true for stateless allocators.
 bool operator==(const Mallocator& other) const
 {
  return true;
 }

 bool operator!=(const Mallocator& other) const
 {
  return !(*this == other);
 }

public:
 size_t max_size() const
 {
  // The following has been carefully written to be independent of
  // the definition of size_t and to avoid signed/unsigned warnings.
  return (static_cast<size_t>(0) - static_cast<size_t>(1)) / sizeof(T);
 }

 T* address(T& r) const
 {
  return &r;
 }

 const T* address(const T& s) const
 {
  return &s;
 }

 void construct(T * const p, const T& t) const
 {
  void * const pv = static_cast<void *>(p);
  new (pv) T(t);
 }

 void destroy(T * const p) const // Defined below.
 {
  p->~T();
 }

 // The following will be different for each allocator.
 T * allocate(const size_t n) const
 {
  // Mallocator prints a diagnostic message to demonstrate
  // what it's doing. Real allocators won't do this.
  //std::cout << "Allocating " << n << (n == 1 ? " object" : " objects") << " of size " << sizeof(T) << "." << std::endl;
  printf ("allocate n=%d size=%d \r\n", n, sizeof(T));

  // The return value of allocate(0) is unspecified.
  // Mallocator returns NULL in order to avoid depending
  // on malloc(0)'s implementation-defined behavior
  // (the implementation can define malloc(0) to return NULL,
  // in which case the bad_alloc check below would fire).
  // All allocators can return NULL in this case.
  if (n == 0)
  {
   return NULL;
  }

  // All allocators should contain an integer overflow check.
  // The Standardization Committee recommends that std::length_error
  // be thrown in the case of integer overflow.
  if (n > max_size())
  {
   throw std::length_error("Mallocator<T>::allocate() - Integer overflow.");
  }

  // Mallocator wraps malloc().
  void * const pv = malloc(n * sizeof(T));

  // Allocators should throw std::bad_alloc in the case of memory allocation failure.
  if (pv == NULL)
  {
   throw std::bad_alloc();
  }

  return static_cast<T *>(pv);
 }

 void deallocate(T * const p, const size_t n) const
 {
  // Mallocator prints a diagnostic message to demonstrate
  // what it's doing. Real allocators won't do this.
  std::cout << "Deallocating " << n << (n == 1 ? " object" : "objects") << " of size " << sizeof(T) << "." << std::endl;

  // Mallocator wraps free().
  free(p);
 }

 // The following will be the same for all allocators that ignore hints.
 template <typename U> T * allocate(const size_t n, const U * /* const hint */) const
 {
  return allocate(n);
 }

 // Allocators are not required to be assignable, so
 // all allocators should have a private unimplemented
 // assignment operator. Note that this will trigger the
 // off-by-default (enabled under /Wall) warning C4626
 // "assignment operator could not be generated because a
 // base class assignment operator is inaccessible" within
 // the STL headers, but that warning is useless.
private:
 Mallocator& operator=(const Mallocator&);
};

Posted by 셈말짓기 :