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
00027 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00028
00029 #pragma warning (push)
00030 #pragma warning (disable: 4530)
00031 #endif
00032
00033 #include <cstring>
00034
00035 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00036 #pragma warning (pop)
00037 #endif
00038
00039 namespace tbb {
00040
00042 namespace internal {
00043
00045
00046 void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p );
00047
00049
00050 void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n );
00051
00053 bool __TBB_EXPORTED_FUNC is_malloc_used_v3();
00054 }
00056
00057 #if _MSC_VER && !defined(__INTEL_COMPILER)
00058
00059 #pragma warning (push)
00060 #pragma warning (disable: 4100)
00061 #endif
00062
00064
00069 template<typename T>
00070 class tbb_allocator {
00071 public:
00072 typedef typename internal::allocator_type<T>::value_type value_type;
00073 typedef value_type* pointer;
00074 typedef const value_type* const_pointer;
00075 typedef value_type& reference;
00076 typedef const value_type& const_reference;
00077 typedef size_t size_type;
00078 typedef ptrdiff_t difference_type;
00079 template<typename U> struct rebind {
00080 typedef tbb_allocator<U> other;
00081 };
00082
00084 enum malloc_type {
00085 scalable,
00086 standard
00087 };
00088
00089 tbb_allocator() throw() {}
00090 tbb_allocator( const tbb_allocator& ) throw() {}
00091 template<typename U> tbb_allocator(const tbb_allocator<U>&) throw() {}
00092
00093 pointer address(reference x) const {return &x;}
00094 const_pointer address(const_reference x) const {return &x;}
00095
00097 pointer allocate( size_type n, const void* = 0) {
00098 return pointer(internal::allocate_via_handler_v3( n * sizeof(value_type) ));
00099 }
00100
00102 void deallocate( pointer p, size_type ) {
00103 internal::deallocate_via_handler_v3(p);
00104 }
00105
00107 size_type max_size() const throw() {
00108 size_type max = static_cast<size_type>(-1) / sizeof (value_type);
00109 return (max > 0 ? max : 1);
00110 }
00111
00113 void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
00114
00116 void destroy( pointer p ) {p->~value_type();}
00117
00119 static malloc_type allocator_type() {
00120 return internal::is_malloc_used_v3() ? standard : scalable;
00121 }
00122 };
00123
00124 #if _MSC_VER && !defined(__INTEL_COMPILER)
00125 #pragma warning (pop)
00126 #endif // warning 4100 is back
00127
00129
00130 template<>
00131 class tbb_allocator<void> {
00132 public:
00133 typedef void* pointer;
00134 typedef const void* const_pointer;
00135 typedef void value_type;
00136 template<typename U> struct rebind {
00137 typedef tbb_allocator<U> other;
00138 };
00139 };
00140
00141 template<typename T, typename U>
00142 inline bool operator==( const tbb_allocator<T>&, const tbb_allocator<U>& ) {return true;}
00143
00144 template<typename T, typename U>
00145 inline bool operator!=( const tbb_allocator<T>&, const tbb_allocator<U>& ) {return false;}
00146
00148
00153 template <typename T, template<typename X> class Allocator = tbb_allocator>
00154 class zero_allocator : public Allocator<T>
00155 {
00156 public:
00157 typedef Allocator<T> base_allocator_type;
00158 typedef typename base_allocator_type::value_type value_type;
00159 typedef typename base_allocator_type::pointer pointer;
00160 typedef typename base_allocator_type::const_pointer const_pointer;
00161 typedef typename base_allocator_type::reference reference;
00162 typedef typename base_allocator_type::const_reference const_reference;
00163 typedef typename base_allocator_type::size_type size_type;
00164 typedef typename base_allocator_type::difference_type difference_type;
00165 template<typename U> struct rebind {
00166 typedef zero_allocator<U, Allocator> other;
00167 };
00168
00169 zero_allocator() throw() { }
00170 zero_allocator(const zero_allocator &a) throw() : base_allocator_type( a ) { }
00171 template<typename U>
00172 zero_allocator(const zero_allocator<U> &a) throw() : base_allocator_type( Allocator<U>( a ) ) { }
00173
00174 pointer allocate(const size_type n, const void *hint = 0 ) {
00175 pointer ptr = base_allocator_type::allocate( n, hint );
00176 std::memset( ptr, 0, n * sizeof(value_type) );
00177 return ptr;
00178 }
00179 };
00180
00182
00183 template<template<typename T> class Allocator>
00184 class zero_allocator<void, Allocator> : public Allocator<void> {
00185 public:
00186 typedef Allocator<void> base_allocator_type;
00187 typedef typename base_allocator_type::value_type value_type;
00188 typedef typename base_allocator_type::pointer pointer;
00189 typedef typename base_allocator_type::const_pointer const_pointer;
00190 template<typename U> struct rebind {
00191 typedef zero_allocator<U, Allocator> other;
00192 };
00193 };
00194
00195 template<typename T1, template<typename X1> class B1, typename T2, template<typename X2> class B2>
00196 inline bool operator==( const zero_allocator<T1,B1> &a, const zero_allocator<T2,B2> &b) {
00197 return static_cast< B1<T1> >(a) == static_cast< B2<T2> >(b);
00198 }
00199 template<typename T1, template<typename X1> class B1, typename T2, template<typename X2> class B2>
00200 inline bool operator!=( const zero_allocator<T1,B1> &a, const zero_allocator<T2,B2> &b) {
00201 return static_cast< B1<T1> >(a) != static_cast< B2<T2> >(b);
00202 }
00203
00204 }
00205
00206 #endif