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 #ifndef __TBB_cache_aligned_allocator_H
00030 #define __TBB_cache_aligned_allocator_H
00031
00032 #include <new>
00033 #include "tbb_stddef.h"
00034 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN
00035 #include <utility>
00036 #endif
00037
00038 namespace tbb {
00039
00041 namespace internal {
00043
00044 size_t __TBB_EXPORTED_FUNC NFS_GetLineSize();
00045
00047
00048 void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint );
00049
00051
00053 void __TBB_EXPORTED_FUNC NFS_Free( void* );
00054 }
00056
00057 #if _MSC_VER && !defined(__INTEL_COMPILER)
00058
00059 #pragma warning (push)
00060 #pragma warning (disable: 4100)
00061 #endif
00062
00064
00067 template<typename T>
00068 class cache_aligned_allocator {
00069 public:
00070 typedef typename internal::allocator_type<T>::value_type value_type;
00071 typedef value_type* pointer;
00072 typedef const value_type* const_pointer;
00073 typedef value_type& reference;
00074 typedef const value_type& const_reference;
00075 typedef size_t size_type;
00076 typedef ptrdiff_t difference_type;
00077 template<typename U> struct rebind {
00078 typedef cache_aligned_allocator<U> other;
00079 };
00080
00081 cache_aligned_allocator() throw() {}
00082 cache_aligned_allocator( const cache_aligned_allocator& ) throw() {}
00083 template<typename U> cache_aligned_allocator(const cache_aligned_allocator<U>&) throw() {}
00084
00085 pointer address(reference x) const {return &x;}
00086 const_pointer address(const_reference x) const {return &x;}
00087
00089 pointer allocate( size_type n, const void* hint=0 ) {
00090
00091 return pointer(internal::NFS_Allocate( n, sizeof(value_type), const_cast<void*>(hint) ));
00092 }
00093
00095 void deallocate( pointer p, size_type ) {
00096 internal::NFS_Free(p);
00097 }
00098
00100 size_type max_size() const throw() {
00101 return (~size_t(0)-internal::NFS_MaxLineSize)/sizeof(value_type);
00102 }
00103
00105 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00106 template<typename... Args>
00107 void construct(pointer p, Args&&... args)
00108 #if __TBB_CPP11_STD_FORWARD_BROKEN
00109 { ::new((void *)p) T((args)...); }
00110 #else
00111 { ::new((void *)p) T(std::forward<Args>(args)...); }
00112 #endif
00113 #else // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00114 void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
00115 #endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00116
00118 void destroy( pointer p ) {p->~value_type();}
00119 };
00120
00121 #if _MSC_VER && !defined(__INTEL_COMPILER)
00122 #pragma warning (pop)
00123 #endif // warning 4100 is back
00124
00126
00127 template<>
00128 class cache_aligned_allocator<void> {
00129 public:
00130 typedef void* pointer;
00131 typedef const void* const_pointer;
00132 typedef void value_type;
00133 template<typename U> struct rebind {
00134 typedef cache_aligned_allocator<U> other;
00135 };
00136 };
00137
00138 template<typename T, typename U>
00139 inline bool operator==( const cache_aligned_allocator<T>&, const cache_aligned_allocator<U>& ) {return true;}
00140
00141 template<typename T, typename U>
00142 inline bool operator!=( const cache_aligned_allocator<T>&, const cache_aligned_allocator<U>& ) {return false;}
00143
00144 }
00145
00146 #endif