一个简单的空间配置器, JJ::allocator:
<span style="font-family:Courier New;font-size:14px;">#ifndef __JJALLOC_
#define __JJALLOC_
#include <new> // for placement new
#include <cstddef> // for ptrdiff_t, size_t
#include <cstdlib> // for exit()
#include <climits> // for UINT_MAX
#include <iostream> // for cerr
namespace JJ {
template <class T>
inline T* _allocate(ptrdiff_t size, T*) {
set_new_handler(0);
T* tmp = (T*)(::operator new((size_t)(size*sizeof(T))));
if (tmp == 0) {
cerr << "out of memory" << endl;
exit(1);
}
return tmp;
}
template <class T>
inline void _deallocate(T* buffer) {
::operator delete(buffer);
}
template <class T1, class T2>
inline void _construct(T1* p, const T2& value) {
new(p) T1(value); //placement new. 将p作为地址传入operate new函数
//不进行分配操作, 调用T1::T1(value)
}
template <class T>
inline void _destroy(T* ptr) {
ptr->~T();
}
template <class T>
class allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template <class U>
struct rebind {
typedef allocator<U> other;
//以list为例, allocator<int>::rebind<node>::other即为allocator<node>
};
//第二个参数是个提示, 实现上可能会利用它来增进区域性(locality), 或者完全忽略之
pointer allocate(size_type n, const void* hint = 0) {
return _allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p, size_type n) {
_deallocate(p);
}
void construct(pointer p, const T& value) {
_construct(p, value);
}
void destroy(pointer p) {
_destroy(p);
}
pointer address(reference x) {
return (pointer)&x;
}
const_pointer const_address(const_reference x) {
return (const_pointer)&x;
}
size_type max_size() const {
return size_type(UINT_MAX / sizeof(T));
}
};
}
#endif</span>
SGI标准空间配置器, std::allocator源码:
<span style="font-family:Courier New;font-size:14px;">#ifndef DEFALLOC_H
#define DEFALLOC_H
#include <new.h>
#include <stddef.h>
#include <stdlib.h>
#include <limits.h>
#include <iostream.h>
#include <algobase.h>
template <class T>
inline T* allocate(ptrdiff_t size, T*) {
set_new_handler(0);
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
if (tmp == 0) {
cerr << "out of memory" << endl;
exit(1);
}
return tmp;
}
template <class T>
inline void deallocate(T* buffer) {
::operator delete(buffer);
}
template <class T>
class allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
pointer allocate(size_type n) {
return ::allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p) { ::deallocate(p); }
pointer address(reference x) { return (pointer)&x; }
const_pointer const_address(const_reference x) {
return (const_pointer)&x;
}
size_type init_page_size() {
return max(size_type(1), size_type(4096/sizeof(T)));
}
size_type max_size() const {
return max(size_type(1), size_type(UINT_MAX/sizeof(T)));
}
};
//模板特化需要加template<>, 此处为gcc特性
class allocator<void> {
public:
typedef void* pointer;
};
#endif
</span>