annotate DEPENDENCIES/generic/include/boost/container/allocator.hpp @ 133:4acb5d8d80b6 tip

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