File indexing completed on 2024-11-15 09:26:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_POOL_ALLOC_HPP
0011 #define BOOST_POOL_ALLOC_HPP
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 #include <boost/limits.hpp>
0071
0072 #include <new>
0073
0074 #include <boost/throw_exception.hpp>
0075 #include <boost/pool/poolfwd.hpp>
0076
0077
0078 #include <boost/pool/singleton_pool.hpp>
0079
0080 #include <boost/detail/workaround.hpp>
0081
0082
0083 #include <boost/config.hpp>
0084
0085
0086 #ifdef BOOST_HAS_VARIADIC_TMPL
0087 #include <utility>
0088 #endif
0089
0090 #ifdef BOOST_POOL_INSTRUMENT
0091 #include <iostream>
0092 #include <iomanip>
0093 #endif
0094
0095
0096 #if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) || \
0097 BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x582))
0098 #define BOOST_NO_PROPER_STL_DEALLOCATE
0099 #endif
0100
0101 namespace boost {
0102
0103 #ifdef BOOST_POOL_INSTRUMENT
0104
0105 template <bool b>
0106 struct debug_info
0107 {
0108 static unsigned allocated;
0109 };
0110
0111 template <bool b>
0112 unsigned debug_info<b>::allocated = 0;
0113
0114 #endif
0115
0116
0117
0118 struct pool_allocator_tag
0119 {
0120 };
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 template <typename T,
0148 typename UserAllocator,
0149 typename Mutex,
0150 unsigned NextSize,
0151 unsigned MaxSize >
0152 class pool_allocator
0153 {
0154 public:
0155 typedef T value_type;
0156 typedef UserAllocator user_allocator;
0157 typedef Mutex mutex;
0158 BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
0159
0160 typedef value_type * pointer;
0161 typedef const value_type * const_pointer;
0162 typedef value_type & reference;
0163 typedef const value_type & const_reference;
0164 typedef typename pool<UserAllocator>::size_type size_type;
0165 typedef typename pool<UserAllocator>::difference_type difference_type;
0166
0167
0168
0169
0170
0171
0172
0173 template <typename U>
0174 struct rebind
0175 {
0176 typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
0177 };
0178
0179 public:
0180 pool_allocator()
0181 {
0182
0183
0184
0185
0186
0187
0188 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
0189 NextSize, MaxSize>::is_from(0);
0190 }
0191
0192
0193
0194
0195
0196
0197 template <typename U>
0198 pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
0199 {
0200
0201
0202
0203
0204
0205 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
0206 NextSize, MaxSize>::is_from(0);
0207 }
0208
0209
0210
0211 static pointer address(reference r)
0212 { return &r; }
0213 static const_pointer address(const_reference s)
0214 { return &s; }
0215 static size_type max_size()
0216 { return (std::numeric_limits<size_type>::max)(); }
0217
0218 #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
0219 template <typename U, typename... Args>
0220 static void construct(U* ptr, Args&&... args)
0221 { new (ptr) U(std::forward<Args>(args)...); }
0222 #else
0223 static void construct(const pointer ptr, const value_type & t)
0224 { new (ptr) T(t); }
0225 #endif
0226
0227 static void destroy(const pointer ptr)
0228 {
0229 ptr->~T();
0230 (void) ptr;
0231 }
0232
0233 bool operator==(const pool_allocator &) const
0234 { return true; }
0235 bool operator!=(const pool_allocator &) const
0236 { return false; }
0237
0238 static pointer allocate(const size_type n)
0239 {
0240 #ifdef BOOST_POOL_INSTRUMENT
0241 debug_info<true>::allocated += n * sizeof(T);
0242 std::cout << "Allocating " << n << " * " << sizeof(T) << " bytes...\n"
0243 "Total allocated is now " << debug_info<true>::allocated << std::endl;
0244 #endif
0245 const pointer ret = static_cast<pointer>(
0246 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
0247 NextSize, MaxSize>::ordered_malloc(n) );
0248 if ((ret == 0) && n)
0249 boost::throw_exception(std::bad_alloc());
0250 return ret;
0251 }
0252 static pointer allocate(const size_type n, const void * const)
0253 {
0254
0255
0256 return allocate(n);
0257 }
0258 static void deallocate(const pointer ptr, const size_type n)
0259 {
0260
0261
0262 #ifdef BOOST_POOL_INSTRUMENT
0263 debug_info<true>::allocated -= n * sizeof(T);
0264 std::cout << "Deallocating " << n << " * " << sizeof(T) << " bytes...\n"
0265 "Total allocated is now " << debug_info<true>::allocated << std::endl;
0266 #endif
0267 #ifdef BOOST_NO_PROPER_STL_DEALLOCATE
0268 if (ptr == 0 || n == 0)
0269 return;
0270 #endif
0271 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
0272 NextSize, MaxSize>::ordered_free(ptr, n);
0273 }
0274 };
0275
0276
0277
0278
0279
0280 template<
0281 typename UserAllocator,
0282 typename Mutex,
0283 unsigned NextSize,
0284 unsigned MaxSize>
0285 class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
0286 {
0287 public:
0288 typedef void* pointer;
0289 typedef const void* const_pointer;
0290 typedef void value_type;
0291
0292
0293
0294
0295
0296
0297 template <class U>
0298 struct rebind
0299 {
0300 typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
0301 };
0302 };
0303
0304
0305 struct fast_pool_allocator_tag
0306 {
0307 };
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 template <typename T,
0345 typename UserAllocator,
0346 typename Mutex,
0347 unsigned NextSize,
0348 unsigned MaxSize >
0349 class fast_pool_allocator
0350 {
0351 public:
0352 typedef T value_type;
0353 typedef UserAllocator user_allocator;
0354 typedef Mutex mutex;
0355 BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
0356
0357 typedef value_type * pointer;
0358 typedef const value_type * const_pointer;
0359 typedef value_type & reference;
0360 typedef const value_type & const_reference;
0361 typedef typename pool<UserAllocator>::size_type size_type;
0362 typedef typename pool<UserAllocator>::difference_type difference_type;
0363
0364
0365
0366
0367
0368
0369
0370 template <typename U>
0371 struct rebind
0372 {
0373 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
0374 };
0375
0376 public:
0377 fast_pool_allocator()
0378 {
0379
0380
0381
0382
0383 singleton_pool<fast_pool_allocator_tag, sizeof(T),
0384 UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
0385 }
0386
0387
0388
0389
0390
0391
0392 template <typename U>
0393 fast_pool_allocator(
0394 const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
0395 {
0396
0397
0398
0399
0400 singleton_pool<fast_pool_allocator_tag, sizeof(T),
0401 UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
0402 }
0403
0404
0405
0406 static pointer address(reference r)
0407 {
0408 return &r;
0409 }
0410 static const_pointer address(const_reference s)
0411 { return &s; }
0412 static size_type max_size()
0413 { return (std::numeric_limits<size_type>::max)(); }
0414
0415 #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
0416 template <typename U, typename... Args>
0417 void construct(U* ptr, Args&&... args)
0418 { new (ptr) U(std::forward<Args>(args)...); }
0419 #else
0420 void construct(const pointer ptr, const value_type & t)
0421 { new (ptr) T(t); }
0422 #endif
0423
0424 void destroy(const pointer ptr)
0425 {
0426 ptr->~T();
0427 (void) ptr;
0428 }
0429
0430 bool operator==(const fast_pool_allocator &) const
0431 { return true; }
0432 bool operator!=(const fast_pool_allocator &) const
0433 { return false; }
0434
0435 static pointer allocate(const size_type n)
0436 {
0437 const pointer ret = (n == 1) ?
0438 static_cast<pointer>(
0439 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
0440 UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ) :
0441 static_cast<pointer>(
0442 singleton_pool<fast_pool_allocator_tag, sizeof(T),
0443 UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) );
0444 if (ret == 0)
0445 boost::throw_exception(std::bad_alloc());
0446 return ret;
0447 }
0448 static pointer allocate(const size_type n, const void * const)
0449 {
0450 return allocate(n);
0451 }
0452 static pointer allocate()
0453 {
0454 const pointer ret = static_cast<pointer>(
0455 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
0456 UserAllocator, Mutex, NextSize, MaxSize>::malloc)() );
0457 if (ret == 0)
0458 boost::throw_exception(std::bad_alloc());
0459 return ret;
0460 }
0461 static void deallocate(const pointer ptr, const size_type n)
0462 {
0463
0464 #ifdef BOOST_NO_PROPER_STL_DEALLOCATE
0465 if (ptr == 0 || n == 0)
0466 return;
0467 #endif
0468 if (n == 1)
0469 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
0470 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
0471 else
0472 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
0473 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n);
0474 }
0475 static void deallocate(const pointer ptr)
0476 {
0477 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
0478 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
0479 }
0480 };
0481
0482
0483
0484
0485
0486 template<
0487 typename UserAllocator,
0488 typename Mutex,
0489 unsigned NextSize,
0490 unsigned MaxSize >
0491 class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
0492 {
0493 public:
0494 typedef void* pointer;
0495 typedef const void* const_pointer;
0496 typedef void value_type;
0497
0498
0499
0500
0501
0502
0503
0504 template <class U> struct rebind
0505 {
0506 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
0507 };
0508 };
0509
0510 }
0511
0512 #endif