00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_cache_aligned_allocator_H
00022 #define __TBB_cache_aligned_allocator_H
00023
00024 #include <new>
00025 #include "tbb_stddef.h"
00026 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN
00027 #include <utility>
00028 #endif
00029
00030 namespace tbb {
00031
00033 namespace internal {
00035
00036 size_t __TBB_EXPORTED_FUNC NFS_GetLineSize();
00037
00039
00040 void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint );
00041
00043
00045 void __TBB_EXPORTED_FUNC NFS_Free( void* );
00046 }
00048
00049 #if _MSC_VER && !defined(__INTEL_COMPILER)
00050
00051 #pragma warning (push)
00052 #pragma warning (disable: 4100)
00053 #endif
00054
00056
00059 template<typename T>
00060 class cache_aligned_allocator {
00061 public:
00062 typedef typename internal::allocator_type<T>::value_type value_type;
00063 typedef value_type* pointer;
00064 typedef const value_type* const_pointer;
00065 typedef value_type& reference;
00066 typedef const value_type& const_reference;
00067 typedef size_t size_type;
00068 typedef ptrdiff_t difference_type;
00069 template<typename U> struct rebind {
00070 typedef cache_aligned_allocator<U> other;
00071 };
00072
00073 cache_aligned_allocator() throw() {}
00074 cache_aligned_allocator( const cache_aligned_allocator& ) throw() {}
00075 template<typename U> cache_aligned_allocator(const cache_aligned_allocator<U>&) throw() {}
00076
00077 pointer address(reference x) const {return &x;}
00078 const_pointer address(const_reference x) const {return &x;}
00079
00081 pointer allocate( size_type n, const void* hint=0 ) {
00082
00083 return pointer(internal::NFS_Allocate( n, sizeof(value_type), const_cast<void*>(hint) ));
00084 }
00085
00087 void deallocate( pointer p, size_type ) {
00088 internal::NFS_Free(p);
00089 }
00090
00092 size_type max_size() const throw() {
00093 return (~size_t(0)-internal::NFS_MaxLineSize)/sizeof(value_type);
00094 }
00095
00097 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00098 template<typename... Args>
00099 void construct(pointer p, Args&&... args)
00100 #if __TBB_CPP11_STD_FORWARD_BROKEN
00101 { ::new((void *)p) T((args)...); }
00102 #else
00103 { ::new((void *)p) T(std::forward<Args>(args)...); }
00104 #endif
00105 #else // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00106 void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
00107 #endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
00108
00110 void destroy( pointer p ) {p->~value_type();}
00111 };
00112
00113 #if _MSC_VER && !defined(__INTEL_COMPILER)
00114 #pragma warning (pop)
00115 #endif // warning 4100 is back
00116
00118
00119 template<>
00120 class cache_aligned_allocator<void> {
00121 public:
00122 typedef void* pointer;
00123 typedef const void* const_pointer;
00124 typedef void value_type;
00125 template<typename U> struct rebind {
00126 typedef cache_aligned_allocator<U> other;
00127 };
00128 };
00129
00130 template<typename T, typename U>
00131 inline bool operator==( const cache_aligned_allocator<T>&, const cache_aligned_allocator<U>& ) {return true;}
00132
00133 template<typename T, typename U>
00134 inline bool operator!=( const cache_aligned_allocator<T>&, const cache_aligned_allocator<U>& ) {return false;}
00135
00136 }
00137
00138 #endif