lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
heap_allocator.h
00001 /*****************************************************/
00002 /* lean Memory                  (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_MEMORY_HEAP_ALLOCATOR
00006 #define LEAN_MEMORY_HEAP_ALLOCATOR
00007 
00008 #include "../lean.h"
00009 #include "../meta/strip.h"
00010 #include "alignment.h"
00011 #include "default_heap.h"
00012 
00013 namespace lean
00014 {
00015 namespace memory
00016 {
00017 
00019 template<class Element, class Heap = default_heap, size_t Alignment = alignof(Element)>
00020 class heap_allocator
00021 {
00022 public:
00024     typedef Heap heap_type;
00025 
00027     typedef typename strip_const<Element>::type value_type;
00028 
00030     typedef typename value_type* pointer;
00032     typedef typename value_type& reference;
00034     typedef typename const value_type* const_pointer;
00036     typedef typename const value_type& const_reference;
00037 
00039     typedef typename heap_type::size_type size_type;
00041     typedef ptrdiff_t difference_type;
00042 
00044     template<class Other>
00045     struct rebind
00046     {
00048         typedef heap_allocator<Other, Heap, Alignment> other;
00049     };
00050     
00052     LEAN_INLINE heap_allocator() { }
00054     template<class Other>
00055     LEAN_INLINE heap_allocator(const heap_allocator<Other, Heap, Alignment> &right) { }
00057     template<class Other>
00058     LEAN_INLINE heap_allocator& operator=(const heap_allocator<Other, Heap, Alignment> &right) { return *this; }
00059     
00061     LEAN_INLINE pointer allocate(size_type count)
00062     {
00063         return reinterpret_cast<pointer>( heap_type::allocate<Alignment>(count * sizeof(value_type)) );
00064     }
00066     LEAN_INLINE pointer allocate(size_type count, const void *)
00067     {
00068         return allocate(count);
00069     }
00071     LEAN_INLINE void deallocate(pointer ptr, size_type)
00072     {
00073         heap_type::free<Alignment>(ptr);
00074     }
00075 
00077     LEAN_INLINE void construct(pointer ptr, const value_type& value)
00078     {
00079         new(reinterpret_cast<void*>(ptr)) Element(value);
00080     }
00082     template<class Other>
00083     LEAN_INLINE void construct(pointer ptr, const Other& value)
00084     {
00085         new(reinterpret_cast<void*>(ptr)) Element(value);
00086     }
00087 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00088 
00089     LEAN_INLINE void construct(pointer ptr, value_type&& value)
00090     {
00091         new(reinterpret_cast<void*>(ptr)) Element(std::forward<value_type>(value));
00092     }
00094     template<class Other>
00095     LEAN_INLINE void construct(pointer ptr, Other&& value)
00096     {
00097         new(reinterpret_cast<void*>(ptr)) Element(std::forward<Other>(value));
00098     }
00099 #endif
00100 
00101     LEAN_INLINE void destroy(pointer ptr)
00102     {
00103         ptr->~Element();
00104     }
00105 
00107     LEAN_INLINE pointer address(reference value) const
00108     {
00109         return reinterpret_cast<pointer>( &reinterpret_cast<char&>(value) );
00110     }
00112     LEAN_INLINE const_pointer address(const_reference value) const
00113     {
00114         return reinterpret_cast<const_pointer>( &reinterpret_cast<const char&>(value) );
00115     }
00116 
00118     LEAN_INLINE size_t max_size() const
00119     {
00120         size_t count = static_cast<size_t>(-1) / sizeof(Element);
00121         return (0 < count) ? count : 1;
00122     }
00123 };
00124 
00125 #ifndef DOXYGEN_SKIP_THIS
00126 
00128 template<class Heap, size_t Alignment>
00129 class heap_allocator<void, Heap, Alignment>
00130 {
00131 public:
00133     typedef Heap heap_type;
00134 
00136     typedef void value_type;
00137 
00139     typedef typename value_type* pointer;
00141     typedef typename const value_type* const_pointer;
00142 
00144     typedef typename heap_type::size_type size_type;
00146     typedef ptrdiff_t difference_type;
00147 
00149     template <class Other>
00150     struct rebind
00151     {
00153         typedef heap_allocator<Other, Heap, Alignment> other;
00154     };
00155     
00157     LEAN_INLINE heap_allocator() { }
00159     template <class Other>
00160     LEAN_INLINE heap_allocator(const heap_allocator<Other, Heap, Alignment> &right) { }
00162     template <class Other>
00163     LEAN_INLINE heap_allocator& operator=(const heap_allocator<Other, Heap, Alignment> &right) { return *this; }
00164 };
00165 
00166 #endif
00167 
00169 template <class Element, class Heap, size_t Alignment, class Other>
00170 LEAN_INLINE bool operator ==(const heap_allocator<Element, Heap, Alignment>&, const heap_allocator<Other, Heap, Alignment>&)
00171 {
00172     return true;
00173 }
00174 
00176 template <class Element, class Heap, size_t Alignment, class Other>
00177 LEAN_INLINE bool operator !=(const heap_allocator<Element, Heap, Alignment>&, const heap_allocator<Other, Heap, Alignment>&)
00178 {
00179     return false;
00180 }
00181 
00182 } // namespace
00183 
00184 using memory::heap_allocator;
00185 
00186 } // namespace
00187 
00188 #endif