2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_DETAILS_ALLOCATOR_H
32 #define CDSLIB_DETAILS_ALLOCATOR_H
34 #include <type_traits>
36 #include <cds/details/defs.h>
37 #include <cds/user_setup/allocator.h>
42 /// Extends \p std::allocator interface to provide semantics like operator \p new and \p delete
44 The class is the wrapper around underlying \p Alloc class.
45 \p Alloc provides the \p std::allocator interface.
47 template <typename T, class Alloc = CDS_DEFAULT_ALLOCATOR >
49 : public std::conditional<
50 std::is_same< T, typename Alloc::value_type>::value
52 , typename Alloc::template rebind<T>::other
56 /// Underlying allocator type
57 typedef typename std::conditional<
58 std::is_same< T, typename Alloc::value_type>::value
60 , typename Alloc::template rebind<T>::other
61 >::type allocator_type;
63 /// \p true if underlined allocator is \p std::allocator, \p false otherwise
64 static CDS_CONSTEXPR bool const c_bStdAllocator = std::is_same< allocator_type, std::allocator<T>>::value;
69 /// Analogue of operator new T(\p src... )
70 template <typename... S>
71 value_type * New( S const&... src )
73 return Construct( allocator_type::allocate(1), src... );
76 /// Analogue of <tt>operator new T( std::forward<Args>(args)... )</tt> (move semantics)
77 template <typename... Args>
78 value_type * MoveNew( Args&&... args )
80 return MoveConstruct( allocator_type::allocate(1), std::forward<Args>(args)... );
83 /// Analogue of operator new T[\p nCount ]
84 value_type * NewArray( size_t nCount )
86 value_type * p = allocator_type::allocate( nCount );
87 for ( size_t i = 0; i < nCount; ++i )
92 /// Analogue of operator new T[\p nCount ].
94 Each item of array of type T is initialized by parameter \p src: T( src )
97 value_type * NewArray( size_t nCount, S const& src )
99 value_type * p = allocator_type::allocate( nCount );
100 for ( size_t i = 0; i < nCount; ++i )
101 Construct( p + i, src );
105 # if CDS_COMPILER == CDS_COMPILER_INTEL
107 value_type * NewBlock( size_t nSize )
109 return Construct( heap_alloc( nSize ));
113 /// Allocates block of memory of size at least \p nSize bytes.
115 Internally, the block is allocated as an array of \p void* pointers,
116 then \p Construct() method is called to initialize \p T.
118 Precondition: <tt> nSize >= sizeof(T) </tt>
120 template <typename... S>
121 value_type * NewBlock( size_t nSize, S const&... src )
123 return Construct( heap_alloc( nSize ), src... );
126 /// Analogue of operator delete
127 void Delete( value_type * p )
129 allocator_type::destroy( p );
130 allocator_type::deallocate( p, 1 );
133 /// Analogue of operator delete []
134 void Delete( value_type * p, size_t nCount )
136 for ( size_t i = 0; i < nCount; ++i )
137 allocator_type::destroy( p + i );
138 allocator_type::deallocate( p, nCount );
141 # if CDS_COMPILER == CDS_COMPILER_INTEL
143 value_type * Construct( void * p )
145 return new( p ) value_type;
149 /// Analogue of placement operator new( \p p ) T( src... )
150 template <typename... S>
151 value_type * Construct( void * p, S const&... src )
153 value_type * pv = new( p ) value_type( src... );
157 /// Analogue of placement <tt>operator new( p ) T( std::forward<Args>(args)... )</tt>
158 template <typename... Args>
159 value_type * MoveConstruct( void * p, Args&&... args )
161 value_type * pv = new( p ) value_type( std::forward<Args>(args)... );
165 /// Rebinds allocator to other type \p Q instead of \p T
166 template <typename Q>
168 typedef Allocator< Q, typename Alloc::template rebind<Q>::other > other ; ///< Rebinding result
173 void * heap_alloc( size_t nByteSize )
175 assert( nByteSize >= sizeof(value_type));
177 size_t const nPtrSize = ( nByteSize + sizeof(void *) - 1 ) / sizeof(void *);
178 typedef typename allocator_type::template rebind< void * >::other void_allocator;
179 return void_allocator().allocate( nPtrSize );
184 /// Deferral removing of the object of type \p T. Helper class
185 template <typename T, typename Alloc = CDS_DEFAULT_ALLOCATOR>
186 struct deferral_deleter {
187 typedef T type ; ///< Type
188 typedef Alloc allocator_type ; ///< Allocator for removing
190 /// Frees the object \p p
192 Caveats: this function uses temporary object of type \ref cds::details::Allocator to free the node \p p.
193 So, the node allocator should be stateless. It is standard requirement for \p std::allocator class objects.
195 Do not use this function directly.
197 static void free( T * p )
199 Allocator<type, allocator_type> a;
204 } // namespace details
207 #endif // #ifndef CDSLIB_DETAILS_ALLOCATOR_H