Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef ALLOCATORS_ALIGNED_H
00036 #define ALLOCATORS_ALIGNED_H
00037
00038 #include <cstdlib>
00039 #include <boost/cstdint.hpp>
00040
00041 namespace allocators
00042 {
00043
00044
00045
00046
00053 inline void* alignedMalloc(size_t size, size_t alignment)
00054 {
00055 const int pointerSize = sizeof(void*);
00056 const int requestedSize = size + alignment - 1 + pointerSize;
00057 void* raw = std::malloc(requestedSize);
00058
00059 if (!raw)
00060 {
00061 return 0;
00062 }
00063
00064 void* start = (uint8_t*)raw + pointerSize;
00065 void* aligned = (void*)(((uintptr_t)((uint8_t*)start+alignment-1)) & ~(alignment-1));
00066 *(void**)((uint8_t*)aligned-pointerSize) = raw;
00067 return aligned;
00068 }
00069
00074 inline void alignedFree(void* aligned)
00075 {
00076 if (!aligned)
00077 {
00078 return;
00079 }
00080
00081 void* raw = *(void**)((uint8_t*)aligned - sizeof(void*));
00082 std::free(raw);
00083 }
00084
00085 template<class T, size_t align> class AlignedAllocator;
00086
00087
00088 template<size_t align>
00089 class AlignedAllocator<void, align>
00090 {
00091 public:
00092 typedef void* pointer;
00093 typedef const void* const_pointer;
00094
00095 typedef void value_type;
00096
00097 template<class U>
00098 struct rebind
00099 {
00100 typedef AlignedAllocator<U, align> other;
00101 };
00102 };
00103
00109 template<class T, size_t align>
00110 class AlignedAllocator
00111 {
00112 public:
00113 typedef size_t size_type;
00114 typedef ptrdiff_t difference_type;
00115 typedef T* pointer;
00116 typedef const T* const_pointer;
00117 typedef T& reference;
00118 typedef const T& const_reference;
00119 typedef T value_type;
00120
00121 template<class U>
00122 struct rebind
00123 {
00124 typedef AlignedAllocator<U, align> other;
00125 };
00126
00127 AlignedAllocator() throw ()
00128 {
00129 }
00130
00131 ~AlignedAllocator() throw ()
00132 {
00133 }
00134
00135 pointer address(reference r) const
00136 {
00137 return &r;
00138 }
00139 const_pointer address(const_reference r) const
00140 {
00141 return &r;
00142 }
00143 size_type max_size() const throw ()
00144 {
00145 return ~size_type(0);
00146 }
00147 pointer allocate(size_type n, typename AlignedAllocator<void, align>::const_pointer hint = 0)
00148 {
00149 void* mem = alignedMalloc(n * sizeof(T), align);
00150 if (!mem)
00151 {
00152 throw std::bad_alloc();
00153 }
00154
00155 return static_cast<pointer>(mem);
00156 }
00157 void deallocate(pointer p, size_type n)
00158 {
00159 alignedFree(p);
00160 }
00161
00162 void construct(pointer p, const_reference val)
00163 {
00164 new (p) T(val);
00165 }
00166 void destroy(pointer p)
00167 {
00168 p->~T();
00169 }
00170 };
00171
00172 }
00173
00174 #endif // ALLOCATORS_ALIGNED_H
00175