Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/container/allocator.hpp @ 102:f46d142149f5
Whoops, finish that update
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:13:41 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
101:c530137014c0 | 102:f46d142149f5 |
---|---|
1 ////////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost | |
4 // Software License, Version 1.0. (See accompanying file | |
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 // | |
7 // See http://www.boost.org/libs/container for documentation. | |
8 // | |
9 ////////////////////////////////////////////////////////////////////////////// | |
10 | |
11 #ifndef BOOST_CONTAINER_ALLOCATOR_HPP | |
12 #define BOOST_CONTAINER_ALLOCATOR_HPP | |
13 | |
14 #ifndef BOOST_CONFIG_HPP | |
15 # include <boost/config.hpp> | |
16 #endif | |
17 | |
18 #if defined(BOOST_HAS_PRAGMA_ONCE) | |
19 # pragma once | |
20 #endif | |
21 | |
22 #include <boost/container/detail/config_begin.hpp> | |
23 #include <boost/container/detail/workaround.hpp> | |
24 #include <boost/container/container_fwd.hpp> | |
25 #include <boost/container/detail/version_type.hpp> | |
26 #include <boost/container/throw_exception.hpp> | |
27 #include <boost/container/detail/alloc_lib_auto_link.hpp> | |
28 #include <boost/container/detail/multiallocation_chain.hpp> | |
29 #include <boost/static_assert.hpp> | |
30 #include <cstddef> | |
31 #include <cassert> | |
32 | |
33 namespace boost { | |
34 namespace container { | |
35 | |
36 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
37 | |
38 template<unsigned Version, unsigned int AllocationDisableMask> | |
39 class allocator<void, Version, AllocationDisableMask> | |
40 { | |
41 typedef allocator<void, Version, AllocationDisableMask> self_t; | |
42 public: | |
43 typedef void value_type; | |
44 typedef void * pointer; | |
45 typedef const void* const_pointer; | |
46 typedef int & reference; | |
47 typedef const int & const_reference; | |
48 typedef std::size_t size_type; | |
49 typedef std::ptrdiff_t difference_type; | |
50 typedef boost::container::container_detail:: | |
51 version_type<self_t, Version> version; | |
52 | |
53 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
54 typedef boost::container::container_detail:: | |
55 basic_multiallocation_chain<void*> multiallocation_chain; | |
56 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
57 | |
58 //!Obtains an allocator that allocates | |
59 //!objects of type T2 | |
60 template<class T2> | |
61 struct rebind | |
62 { | |
63 typedef allocator< T2 | |
64 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
65 , Version, AllocationDisableMask | |
66 #endif | |
67 > other; | |
68 }; | |
69 | |
70 //!Default constructor | |
71 //!Never throws | |
72 allocator() | |
73 {} | |
74 | |
75 //!Constructor from other allocator. | |
76 //!Never throws | |
77 allocator(const allocator &) | |
78 {} | |
79 | |
80 //!Constructor from related allocator. | |
81 //!Never throws | |
82 template<class T2> | |
83 allocator(const allocator<T2, Version, AllocationDisableMask> &) | |
84 {} | |
85 }; | |
86 | |
87 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
88 | |
89 //!\file | |
90 //! This class is an extended STL-compatible that offers advanced allocation mechanism | |
91 //!(in-place expansion, shrinking, burst-allocation...) | |
92 //! | |
93 //! This allocator is a wrapper around a modified DLmalloc. | |
94 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
95 template<class T> | |
96 #else | |
97 //! If Version is 1, the allocator is a STL conforming allocator. If Version is 2, | |
98 //! the allocator offers advanced expand in place and burst allocation capabilities. | |
99 // | |
100 //! AllocationDisableMask works only if Version is 2 and it can be an inclusive OR | |
101 //! of allocation types the user wants to disable. | |
102 template<class T, unsigned Version, unsigned int AllocationDisableMask> | |
103 #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED | |
104 class allocator | |
105 { | |
106 typedef unsigned int allocation_type; | |
107 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
108 private: | |
109 | |
110 //Self type | |
111 typedef allocator<T, Version, AllocationDisableMask> self_t; | |
112 | |
113 //Not assignable from related allocator | |
114 template<class T2, unsigned int Version2, unsigned int AllocationDisableMask2> | |
115 allocator& operator=(const allocator<T2, Version2, AllocationDisableMask2>&); | |
116 | |
117 //Not assignable from other allocator | |
118 allocator& operator=(const allocator&); | |
119 | |
120 static const unsigned int ForbiddenMask = | |
121 BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BWD | BOOST_CONTAINER_EXPAND_FWD ; | |
122 | |
123 //The mask can't disable all the allocation types | |
124 BOOST_STATIC_ASSERT(( (AllocationDisableMask & ForbiddenMask) != ForbiddenMask )); | |
125 | |
126 //The mask is only valid for version 2 allocators | |
127 BOOST_STATIC_ASSERT(( Version != 1 || (AllocationDisableMask == 0) )); | |
128 | |
129 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
130 | |
131 public: | |
132 typedef T value_type; | |
133 typedef T * pointer; | |
134 typedef const T * const_pointer; | |
135 typedef T & reference; | |
136 typedef const T & const_reference; | |
137 typedef std::size_t size_type; | |
138 typedef std::ptrdiff_t difference_type; | |
139 | |
140 typedef boost::container::container_detail:: | |
141 version_type<self_t, Version> version; | |
142 | |
143 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
144 typedef boost::container::container_detail:: | |
145 basic_multiallocation_chain<void*> void_multiallocation_chain; | |
146 | |
147 typedef boost::container::container_detail:: | |
148 transform_multiallocation_chain | |
149 <void_multiallocation_chain, T> multiallocation_chain; | |
150 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
151 | |
152 //!Obtains an allocator that allocates | |
153 //!objects of type T2 | |
154 template<class T2> | |
155 struct rebind | |
156 { | |
157 typedef allocator<T2, Version, AllocationDisableMask> other; | |
158 }; | |
159 | |
160 //!Default constructor | |
161 //!Never throws | |
162 allocator() BOOST_NOEXCEPT_OR_NOTHROW | |
163 {} | |
164 | |
165 //!Constructor from other allocator. | |
166 //!Never throws | |
167 allocator(const allocator &) BOOST_NOEXCEPT_OR_NOTHROW | |
168 {} | |
169 | |
170 //!Constructor from related allocator. | |
171 //!Never throws | |
172 template<class T2> | |
173 allocator(const allocator<T2 | |
174 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED | |
175 , Version, AllocationDisableMask | |
176 #endif | |
177 > &) BOOST_NOEXCEPT_OR_NOTHROW | |
178 {} | |
179 | |
180 //!Allocates memory for an array of count elements. | |
181 //!Throws std::bad_alloc if there is no enough memory | |
182 //!If Version is 2, this allocated memory can only be deallocated | |
183 //!with deallocate() or (for Version == 2) deallocate_many() | |
184 pointer allocate(size_type count, const void * hint= 0) | |
185 { | |
186 (void)hint; | |
187 if(count > this->max_size()) | |
188 boost::container::throw_bad_alloc(); | |
189 void *ret = boost_cont_malloc(count*sizeof(T)); | |
190 if(!ret) | |
191 boost::container::throw_bad_alloc(); | |
192 return static_cast<pointer>(ret); | |
193 } | |
194 | |
195 //!Deallocates previously allocated memory. | |
196 //!Never throws | |
197 void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW | |
198 { boost_cont_free(ptr); } | |
199 | |
200 //!Returns the maximum number of elements that could be allocated. | |
201 //!Never throws | |
202 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW | |
203 { return size_type(-1)/sizeof(T); } | |
204 | |
205 //!Swaps two allocators, does nothing | |
206 //!because this allocator is stateless | |
207 friend void swap(self_t &, self_t &) BOOST_NOEXCEPT_OR_NOTHROW | |
208 {} | |
209 | |
210 //!An allocator always compares to true, as memory allocated with one | |
211 //!instance can be deallocated by another instance | |
212 friend bool operator==(const allocator &, const allocator &) BOOST_NOEXCEPT_OR_NOTHROW | |
213 { return true; } | |
214 | |
215 //!An allocator always compares to false, as memory allocated with one | |
216 //!instance can be deallocated by another instance | |
217 friend bool operator!=(const allocator &, const allocator &) BOOST_NOEXCEPT_OR_NOTHROW | |
218 { return false; } | |
219 | |
220 //!An advanced function that offers in-place expansion shrink to fit and new allocation | |
221 //!capabilities. Memory allocated with this function can only be deallocated with deallocate() | |
222 //!or deallocate_many(). | |
223 //!This function is available only with Version == 2 | |
224 pointer allocation_command(allocation_type command, | |
225 size_type limit_size, | |
226 size_type &prefer_in_recvd_out_size, | |
227 pointer &reuse) | |
228 { | |
229 BOOST_STATIC_ASSERT(( Version > 1 )); | |
230 const allocation_type mask(AllocationDisableMask); | |
231 command &= ~mask; | |
232 pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); | |
233 if(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)) | |
234 boost::container::throw_bad_alloc(); | |
235 return ret; | |
236 } | |
237 | |
238 //!Returns maximum the number of objects the previously allocated memory | |
239 //!pointed by p can hold. | |
240 //!Memory must not have been allocated with | |
241 //!allocate_one or allocate_individual. | |
242 //!This function is available only with Version == 2 | |
243 size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW | |
244 { | |
245 BOOST_STATIC_ASSERT(( Version > 1 )); | |
246 return boost_cont_size(p); | |
247 } | |
248 | |
249 //!Allocates just one object. Memory allocated with this function | |
250 //!must be deallocated only with deallocate_one(). | |
251 //!Throws bad_alloc if there is no enough memory | |
252 //!This function is available only with Version == 2 | |
253 pointer allocate_one() | |
254 { | |
255 BOOST_STATIC_ASSERT(( Version > 1 )); | |
256 return this->allocate(1); | |
257 } | |
258 | |
259 //!Allocates many elements of size == 1. | |
260 //!Elements must be individually deallocated with deallocate_one() | |
261 //!This function is available only with Version == 2 | |
262 void allocate_individual(std::size_t num_elements, multiallocation_chain &chain) | |
263 { | |
264 BOOST_STATIC_ASSERT(( Version > 1 )); | |
265 this->allocate_many(1, num_elements, chain); | |
266 } | |
267 | |
268 //!Deallocates memory previously allocated with allocate_one(). | |
269 //!You should never use deallocate_one to deallocate memory allocated | |
270 //!with other functions different from allocate_one() or allocate_individual. | |
271 //Never throws | |
272 void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW | |
273 { | |
274 BOOST_STATIC_ASSERT(( Version > 1 )); | |
275 return this->deallocate(p, 1); | |
276 } | |
277 | |
278 //!Deallocates memory allocated with allocate_one() or allocate_individual(). | |
279 //!This function is available only with Version == 2 | |
280 void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW | |
281 { | |
282 BOOST_STATIC_ASSERT(( Version > 1 )); | |
283 return this->deallocate_many(chain); | |
284 } | |
285 | |
286 //!Allocates many elements of size elem_size. | |
287 //!Elements must be individually deallocated with deallocate() | |
288 //!This function is available only with Version == 2 | |
289 void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain) | |
290 { | |
291 BOOST_STATIC_ASSERT(( Version > 1 ));/* | |
292 boost_cont_memchain ch; | |
293 BOOST_CONTAINER_MEMCHAIN_INIT(&ch); | |
294 if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){ | |
295 boost::container::throw_bad_alloc(); | |
296 } | |
297 chain.incorporate_after(chain.before_begin() | |
298 ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch) | |
299 ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) | |
300 ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/ | |
301 if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){ | |
302 boost::container::throw_bad_alloc(); | |
303 } | |
304 } | |
305 | |
306 //!Allocates n_elements elements, each one of size elem_sizes[i] | |
307 //!Elements must be individually deallocated with deallocate() | |
308 //!This function is available only with Version == 2 | |
309 void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) | |
310 { | |
311 BOOST_STATIC_ASSERT(( Version > 1 )); | |
312 boost_cont_memchain ch; | |
313 BOOST_CONTAINER_MEMCHAIN_INIT(&ch); | |
314 if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){ | |
315 boost::container::throw_bad_alloc(); | |
316 } | |
317 chain.incorporate_after(chain.before_begin() | |
318 ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch) | |
319 ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) | |
320 ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) ); | |
321 /* | |
322 if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){ | |
323 boost::container::throw_bad_alloc(); | |
324 }*/ | |
325 } | |
326 | |
327 //!Deallocates several elements allocated by | |
328 //!allocate_many(), allocate(), or allocation_command(). | |
329 //!This function is available only with Version == 2 | |
330 void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW | |
331 { | |
332 BOOST_STATIC_ASSERT(( Version > 1 )); | |
333 boost_cont_memchain ch; | |
334 void *beg(&*chain.begin()), *last(&*chain.last()); | |
335 size_t size(chain.size()); | |
336 BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size); | |
337 boost_cont_multidealloc(&ch); | |
338 //boost_cont_multidealloc(reinterpret_cast<boost_cont_memchain *>(&chain)); | |
339 } | |
340 | |
341 private: | |
342 | |
343 pointer priv_allocation_command | |
344 (allocation_type command, std::size_t limit_size | |
345 ,size_type &prefer_in_recvd_out_size | |
346 ,pointer &reuse_ptr) | |
347 { | |
348 std::size_t const preferred_size = prefer_in_recvd_out_size; | |
349 boost_cont_command_ret_t ret = {0 , 0}; | |
350 if((limit_size > this->max_size()) | (preferred_size > this->max_size())){ | |
351 return pointer(); | |
352 } | |
353 std::size_t l_size = limit_size*sizeof(T); | |
354 std::size_t p_size = preferred_size*sizeof(T); | |
355 std::size_t r_size; | |
356 { | |
357 void* reuse_ptr_void = reuse_ptr; | |
358 ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); | |
359 reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0; | |
360 } | |
361 prefer_in_recvd_out_size = r_size/sizeof(T); | |
362 return (pointer)ret.first; | |
363 } | |
364 }; | |
365 | |
366 } //namespace container { | |
367 } //namespace boost { | |
368 | |
369 #include <boost/container/detail/config_end.hpp> | |
370 | |
371 #endif //BOOST_CONTAINER_ALLOCATOR_HPP | |
372 |