3 #ifndef CDSLIB_DETAILS_ALLOCATOR_H
4 #define CDSLIB_DETAILS_ALLOCATOR_H
8 #include <cds/details/defs.h>
9 #include <cds/user_setup/allocator.h>
14 /// Extends \p std::allocator interface to provide semantics like operator \p new and \p delete
16 The class is the wrapper around underlying \p Alloc class.
17 \p Alloc provides the \p std::allocator interface.
19 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR >
21 : public std::conditional<
22 std::is_same< T, typename Alloc::value_type>::value
24 , typename Alloc::template rebind<T>::other
28 /// Underlying allocator type
29 typedef typename std::conditional<
30 std::is_same< T, typename Alloc::value_type>::value
32 , typename Alloc::template rebind<T>::other
33 >::type allocator_type;
35 /// \p true if underlined allocator is \p std::allocator, \p false otherwise
36 static CDS_CONSTEXPR bool const c_bStdAllocator = std::is_same< allocator_type, std::allocator<T>>::value;
41 /// Analogue of operator new T(\p src... )
42 template <typename... S>
43 value_type * New( S const&... src )
45 # if CDS_THREAD_SANITIZER_ENABLED
46 if ( c_bStdAllocator ) {
47 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
49 value_type * pv = Construct( allocator_type::allocate(1), src... );
50 if ( c_bStdAllocator ) {
51 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
55 return Construct( allocator_type::allocate(1), src... );
59 /// Analogue of <tt>operator new T( std::forward<Args>(args)... )</tt> (move semantics)
60 template <typename... Args>
61 value_type * MoveNew( Args&&... args )
63 # if CDS_THREAD_SANITIZER_ENABLED
64 if ( c_bStdAllocator ) {
65 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
67 value_type * pv = MoveConstruct( allocator_type::allocate(1), std::forward<Args>(args)... );
68 if ( c_bStdAllocator ) {
69 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
73 return MoveConstruct( allocator_type::allocate(1), std::forward<Args>(args)... );
77 /// Analogue of operator new T[\p nCount ]
78 value_type * NewArray( size_t nCount )
80 # if CDS_THREAD_SANITIZER_ENABLED
81 if ( c_bStdAllocator ) {
82 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
85 value_type * p = allocator_type::allocate( nCount );
86 # if CDS_THREAD_SANITIZER_ENABLED
87 if ( c_bStdAllocator ) {
88 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
91 for ( size_t i = 0; i < nCount; ++i )
96 /// Analogue of operator new T[\p nCount ].
98 Each item of array of type T is initialized by parameter \p src: T( src )
100 template <typename S>
101 value_type * NewArray( size_t nCount, S const& src )
103 # if CDS_THREAD_SANITIZER_ENABLED
104 if ( c_bStdAllocator ) {
105 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
108 value_type * p = allocator_type::allocate( nCount );
109 # if CDS_THREAD_SANITIZER_ENABLED
110 if ( c_bStdAllocator ) {
111 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
114 for ( size_t i = 0; i < nCount; ++i )
115 Construct( p + i, src );
119 # if CDS_COMPILER == CDS_COMPILER_INTEL
121 value_type * NewBlock( size_t nSize )
123 return Construct( heap_alloc( nSize ));
127 /// Allocates block of memory of size at least \p nSize bytes.
129 Internally, the block is allocated as an array of \p void* pointers,
130 then \p Construct() method is called to initialize \p T.
132 Precondition: <tt> nSize >= sizeof(T) </tt>
134 template <typename... S>
135 value_type * NewBlock( size_t nSize, S const&... src )
137 return Construct( heap_alloc( nSize ), src... );
140 /// Analogue of operator delete
141 void Delete( value_type * p )
143 // TSan false positive possible
144 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
145 allocator_type::destroy( p );
146 allocator_type::deallocate( p, 1 );
147 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
150 /// Analogue of operator delete []
151 void Delete( value_type * p, size_t nCount )
153 // TSan false positive possible
154 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
155 for ( size_t i = 0; i < nCount; ++i )
156 allocator_type::destroy( p + i );
157 allocator_type::deallocate( p, nCount );
158 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
161 # if CDS_COMPILER == CDS_COMPILER_INTEL
163 value_type * Construct( void * p )
165 return new( p ) value_type;
169 /// Analogue of placement operator new( \p p ) T( src... )
170 template <typename... S>
171 value_type * Construct( void * p, S const&... src )
173 // TSan false positive possible
174 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
175 value_type * pv = new( p ) value_type( src... );
176 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
180 /// Analogue of placement <tt>operator new( p ) T( std::forward<Args>(args)... )</tt>
181 template <typename... Args>
182 value_type * MoveConstruct( void * p, Args&&... args )
184 // TSan false positive possible
185 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
186 value_type * pv = new( p ) value_type( std::forward<Args>(args)... );
187 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
191 /// Rebinds allocator to other type \p Q instead of \p T
192 template <typename Q>
194 typedef Allocator< Q, typename Alloc::template rebind<Q>::other > other ; ///< Rebinding result
199 void * heap_alloc( size_t nByteSize )
201 assert( nByteSize >= sizeof(value_type));
203 size_t const nPtrSize = ( nByteSize + sizeof(void *) - 1 ) / sizeof(void *);
204 typedef typename allocator_type::template rebind< void * >::other void_allocator;
205 # if CDS_THREAD_SANITIZER_ENABLED
206 if ( c_bStdAllocator ) {
207 CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
210 void * p = void_allocator().allocate( nPtrSize );
211 # if CDS_THREAD_SANITIZER_ENABLED
212 if ( c_bStdAllocator ) {
213 CDS_TSAN_ANNOTATE_IGNORE_WRITES_END;
221 /// Deferral removing of the object of type \p T. Helper class
222 template <typename T, typename Alloc = CDS_DEFAULT_ALLOCATOR>
223 struct deferral_deleter {
224 typedef T type ; ///< Type
225 typedef Alloc allocator_type ; ///< Allocator for removing
227 /// Frees the object \p p
229 Caveats: this function uses temporary object of type \ref cds::details::Allocator to free the node \p p.
230 So, the node allocator should be stateless. It is standard requirement for \p std::allocator class objects.
232 Do not use this function directly.
234 static void free( T * p )
236 Allocator<type, allocator_type> a;
241 } // namespace details
244 #endif // #ifndef CDSLIB_DETAILS_ALLOCATOR_H