前言
以STL的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体地说是指容器,container)的背后,默默工作,默默付出。但若以 STL 的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL 的操作对象(所有的数值)都存放在容器之内,而容器一定需要配置空间以置放资料。不先掌握空间配置器的原理,难免在阅读其它STL组件的实现时处处遇到挡路石。
———— 《STL源码剖析》侯捷
虽然 SGI 也定义有一个符合部分标准、名为 allocator 的配置器,但 SGI 自己从未用过它,也不建议我们使用。主要原因是效率不佳,只把 C++ 的 ::operator new
和 ::operator delete
做一层简单的包装而已。
allocator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| #ifndef TINYSTL_ALLOCATOR_H_ #define TINYSTL_ALLOCATOR_H_
#include <cstddef> #include <new> #include "construct.h" #include "util.h"
namespace tinystl {
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;
public: static T* allocate(); static T* allocate(size_type n);
static void deallocate(T* ptr); static void deallocate(T* ptr, size_type n); static void construct(T* ptr); static void construct(T* ptr, const T& value); static void construct(T* ptr, T&& value); template <class... Args> static void construct(T* ptr, Args&&... args);
static void destroy(T* ptr); static void destroy(T* first, T* last); };
template <class T> T* allocator<T>::allocate() { return static_cast<T*>(::operator new (sizeof(T))); }
template <class T> T* allocator<T>::allocate(size_type n) { if (n == 0) return nullptr; return static_cast<T*>(::operator new (n * sizeof(T))); }
template <class T> void allocator<T>::deallocate(T* ptr) { if (ptr == nullptr) return; ::operator delete(ptr); }
template <class T> void allocator<T>::deallocate(T* ptr, size_type ) { if (ptr == nullptr) return; ::operator delete(ptr); }
template <class T> void allocator<T>::construct(T* ptr) { tinystl::construct(ptr); }
template <class T> void allocator<T>::construct(T* ptr, const T& value) { tinystl::construct(ptr, value); }
template <class T> void allocator<T>::construct(T* ptr, T&& value) { tinystl::construct(ptr, tinystl::move(value)); }
template <class T> template <class... Args> void allocator<T>::construct(T* ptr, Args&&... args) { tinystl::construct(ptr, tinystl::forward<Args>(args)...); }
template <class T> void allocator<T>::destroy(T* ptr) { tinystl::destroy(ptr); }
template <class T> void allocator<T>::destroy(T* first, T* last) { tinystl::destroy(first, last); }
}
#endif
|