00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_tbb_allocator_H
00022 #define __TBB_tbb_allocator_H
00023
00024 #include "tbb_stddef.h"
00025 #include <new>
00026 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN
00027 #include <utility>
00028 #endif
00029
00030 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00031
00032 #pragma warning (push)
00033 #pragma warning (disable: 4530)
00034 #endif
00035
00036 #include <cstring>
00037
00038 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00039 #pragma warning (pop)
00040 #endif
00041
00042 namespace tbb {
00043
00045 namespace internal {
00046
00048
00049 void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p );
00050
00052
00053 void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n );
00054
00056 bool __TBB_EXPORTED_FUNC is_malloc_used_v3();
00057 }
00059
00060 #if _MSC_VER && !defined(__INTEL_COMPILER)
00061
00062 #pragma warning (push)
00063 #pragma warning (disable: 4100)
00064 #endif
00065
00067
00072 template<typename T>
00073 class tbb_allocator {
00074 public:
00075 typedef typename internal::allocator_type<T>::value_type value_type;
00076 typedef value_type* pointer;
00077 typedef const value_type* const_pointer;
00078 typedef value_type& reference;
00079 typedef const value_type& const_reference;
00080 typedef size_t size_type;
00081 typedef ptrdiff_t difference_type;
00082 template<typename U> struct rebind {
00083 typedef tbb_allocator<U> other;
00084 };
00085
00087 enum malloc_type {
00088 scalable,
00089 standard
00090 };
00091
00092 tbb_allocator() throw() {}
00093 tbb_allocator( const tbb_allocator& ) throw() {}
00094 template<typename U> tbb_allocator(const tbb_allocator<U>&) throw() {}
00095
00096 pointer address(reference x) const {return &x;}
00097 const_pointer address(const_reference x) const {return &x;}
00098
00100 pointer allocate( size_type n, const void* = 0) {
00101 return pointer(internal::allocate_via_handler_v3( n * sizeof(value_type) ));
00102 }
00103
00105 void deallocate( pointer p, size_type ) {
00106 internal::deallocate_via_handler_v3(p);
00107 }
00108
00110 size_type max_size() const throw() {
00111 size_type max = static_cast<size_type>(-1) / sizeof (value_type);
00112 return (max > 0 ? max : 1);
00113 }
00114
00116 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00117 template<typename... Args>
00118 void construct(pointer p, Args&&... args)
00119 #if __TBB_CPP11_STD_FORWARD_BROKEN
00120 { ::new((void *)p) T((args)...); }
00121 #else
00122 { ::new((void *)p) T(std::forward<Args>(args)...); }
00123 #endif
00124 #else // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00125 void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
00126 #endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00127
00129 void destroy( pointer p ) {p->~value_type();}
00130
00132 static malloc_type allocator_type() {
00133 return internal::is_malloc_used_v3() ? standard : scalable;
00134 }
00135 };
00136
00137 #if _MSC_VER && !defined(__INTEL_COMPILER)
00138 #pragma warning (pop)
00139 #endif // warning 4100 is back
00140
00142
00143 template<>
00144 class tbb_allocator<void> {
00145 public:
00146 typedef void* pointer;
00147 typedef const void* const_pointer;
00148 typedef void value_type;
00149 template<typename U> struct rebind {
00150 typedef tbb_allocator<U> other;
00151 };
00152 };
00153
00154 template<typename T, typename U>
00155 inline bool operator==( const tbb_allocator<T>&, const tbb_allocator<U>& ) {return true;}
00156
00157 template<typename T, typename U>
00158 inline bool operator!=( const tbb_allocator<T>&, const tbb_allocator<U>& ) {return false;}
00159
00161
00166 template <typename T, template<typename X> class Allocator = tbb_allocator>
00167 class zero_allocator : public Allocator<T>
00168 {
00169 public:
00170 typedef Allocator<T> base_allocator_type;
00171 typedef typename base_allocator_type::value_type value_type;
00172 typedef typename base_allocator_type::pointer pointer;
00173 typedef typename base_allocator_type::const_pointer const_pointer;
00174 typedef typename base_allocator_type::reference reference;
00175 typedef typename base_allocator_type::const_reference const_reference;
00176 typedef typename base_allocator_type::size_type size_type;
00177 typedef typename base_allocator_type::difference_type difference_type;
00178 template<typename U> struct rebind {
00179 typedef zero_allocator<U, Allocator> other;
00180 };
00181
00182 zero_allocator() throw() { }
00183 zero_allocator(const zero_allocator &a) throw() : base_allocator_type( a ) { }
00184 template<typename U>
00185 zero_allocator(const zero_allocator<U> &a) throw() : base_allocator_type( Allocator<U>( a ) ) { }
00186
00187 pointer allocate(const size_type n, const void *hint = 0 ) {
00188 pointer ptr = base_allocator_type::allocate( n, hint );
00189 std::memset( ptr, 0, n * sizeof(value_type) );
00190 return ptr;
00191 }
00192 };
00193
00195
00196 template<template<typename T> class Allocator>
00197 class zero_allocator<void, Allocator> : public Allocator<void> {
00198 public:
00199 typedef Allocator<void> base_allocator_type;
00200 typedef typename base_allocator_type::value_type value_type;
00201 typedef typename base_allocator_type::pointer pointer;
00202 typedef typename base_allocator_type::const_pointer const_pointer;
00203 template<typename U> struct rebind {
00204 typedef zero_allocator<U, Allocator> other;
00205 };
00206 };
00207
00208 template<typename T1, template<typename X1> class B1, typename T2, template<typename X2> class B2>
00209 inline bool operator==( const zero_allocator<T1,B1> &a, const zero_allocator<T2,B2> &b) {
00210 return static_cast< B1<T1> >(a) == static_cast< B2<T2> >(b);
00211 }
00212 template<typename T1, template<typename X1> class B1, typename T2, template<typename X2> class B2>
00213 inline bool operator!=( const zero_allocator<T1,B1> &a, const zero_allocator<T2,B2> &b) {
00214 return static_cast< B1<T1> >(a) != static_cast< B2<T2> >(b);
00215 }
00216
00217 }
00218
00219 #endif