00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00048
#ifndef __GLIBCPP_INTERNAL_ALLOC_H
00049
#define __GLIBCPP_INTERNAL_ALLOC_H
00050
00085
#include <cstddef>
00086
#include <cstdlib>
00087
#include <cstring>
00088
#include <cassert>
00089
#include <bits/functexcept.h>
00090
#include <bits/stl_threads.h>
00091
00092
#include <bits/atomicity.h>
00093
00094
namespace std
00095 {
00104 class __new_alloc
00105 {
00106
public:
00107
static void*
00108 allocate(size_t __n)
00109 {
return ::operator new(__n); }
00110
00111
static void
00112 deallocate(
void* __p, size_t)
00113 { ::operator
delete(__p); }
00114 };
00115
00116
00127
template<
int __inst>
00128 class __malloc_alloc_template
00129 {
00130
private:
00131
static void* _S_oom_malloc(size_t);
00132
00133
00134
static void* _S_oom_realloc(
void*, size_t);
00135
00136
static void (* __malloc_alloc_oom_handler)();
00137
00138
public:
00139
static void*
00140 allocate(size_t __n)
00141 {
00142
void* __result = malloc(__n);
00143
if (__builtin_expect(__result == 0, 0))
00144 __result = _S_oom_malloc(__n);
00145
return __result;
00146 }
00147
00148
static void
00149 deallocate(
void* __p, size_t )
00150 { free(__p); }
00151
00152
00153
static void*
00154 reallocate(
void* __p, size_t , size_t __new_sz)
00155 {
00156
void* __result = realloc(__p, __new_sz);
00157
if (__builtin_expect(__result == 0, 0))
00158 __result = _S_oom_realloc(__p, __new_sz);
00159
return __result;
00160 }
00161
00162
static void (* __set_malloc_handler(
void (*__f)()))()
00163 {
00164 void (* __old)() = __malloc_alloc_oom_handler;
00165 __malloc_alloc_oom_handler = __f;
00166
return __old;
00167 }
00168 };
00169
00170
00171
template<
int __inst>
00172 void (*
__malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;
00173
00174
template<
int __inst>
00175
void*
00176
__malloc_alloc_template<__inst>::
00177
_S_oom_malloc(size_t __n)
00178 {
00179 void (* __my_malloc_handler)();
00180
void* __result;
00181
00182
for (;;)
00183 {
00184 __my_malloc_handler = __malloc_alloc_oom_handler;
00185
if (__builtin_expect(__my_malloc_handler == 0, 0))
00186 __throw_bad_alloc();
00187 (*__my_malloc_handler)();
00188 __result = malloc(__n);
00189
if (__result)
00190
return __result;
00191 }
00192 }
00193
00194
00195
template<
int __inst>
00196
void*
00197 __malloc_alloc_template<__inst>::
00198 _S_oom_realloc(
void* __p, size_t __n)
00199 {
00200 void (* __my_malloc_handler)();
00201
void* __result;
00202
00203
for (;;)
00204 {
00205 __my_malloc_handler = __malloc_alloc_oom_handler;
00206
if (__builtin_expect(__my_malloc_handler == 0, 0))
00207 __throw_bad_alloc();
00208 (*__my_malloc_handler)();
00209 __result = realloc(__p, __n);
00210
if (__result)
00211
return __result;
00212 }
00213 }
00214
00215
00216
typedef __new_alloc __mem_interface;
00217
00229
template<
typename _Tp,
typename _Alloc>
00230 class __simple_alloc
00231 {
00232
public:
00233
static _Tp*
00234 allocate(size_t __n)
00235 {
00236 _Tp* __ret = 0;
00237
if (__n)
00238 __ret = static_cast<_Tp*>(_Alloc::allocate(__n *
sizeof(_Tp)));
00239
return __ret;
00240 }
00241
00242
static _Tp*
00243 allocate()
00244 {
return (_Tp*) _Alloc::allocate(
sizeof (_Tp)); }
00245
00246
static void
00247 deallocate(_Tp* __p, size_t __n)
00248 {
if (0 != __n) _Alloc::deallocate(__p, __n *
sizeof (_Tp)); }
00249
00250
static void
00251 deallocate(_Tp* __p)
00252 { _Alloc::deallocate(__p,
sizeof (_Tp)); }
00253 };
00254
00255
00270
template<
typename _Alloc>
00271 class __debug_alloc
00272 {
00273
private:
00274
00275
00276
enum {_S_extra = 8};
00277
00278
public:
00279
static void*
00280 allocate(size_t __n)
00281 {
00282
char* __result = (
char*)_Alloc::allocate(__n + (
int) _S_extra);
00283 *(size_t*)__result = __n;
00284
return __result + (
int) _S_extra;
00285 }
00286
00287
static void
00288 deallocate(
void* __p, size_t __n)
00289 {
00290
char* __real_p = (
char*)__p - (
int) _S_extra;
00291 assert(*(size_t*)__real_p == __n);
00292 _Alloc::deallocate(__real_p, __n + (
int) _S_extra);
00293 }
00294
00295
00296
static void*
00297 reallocate(
void* __p, size_t __old_sz, size_t __new_sz)
00298 {
00299
char* __real_p = (
char*)__p - (
int) _S_extra;
00300 assert(*(size_t*)__real_p == __old_sz);
00301
char* __result = (
char*) _Alloc::reallocate(__real_p,
00302 __old_sz + (
int) _S_extra,
00303 __new_sz + (
int) _S_extra);
00304 *(size_t*)__result = __new_sz;
00305
return __result + (
int) _S_extra;
00306 }
00307 };
00308
00309
00340
template<
bool __threads,
int __inst>
00341 class __default_alloc_template
00342 {
00343
private:
00344
enum {_ALIGN = 8};
00345
enum {_MAX_BYTES = 128};
00346
enum {_NFREELISTS = _MAX_BYTES / _ALIGN};
00347
00348
union _Obj
00349 {
00350
union _Obj* _M_free_list_link;
00351
char _M_client_data[1];
00352 };
00353
00354
static _Obj*
volatile _S_free_list[_NFREELISTS];
00355
00356
00357
static char* _S_start_free;
00358
static char* _S_end_free;
00359
static size_t _S_heap_size;
00360
00361
static _STL_mutex_lock _S_node_allocator_lock;
00362
00363
static size_t
00364 _S_round_up(size_t __bytes)
00365 {
return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }
00366
00367
static size_t
00368 _S_freelist_index(size_t __bytes)
00369 {
return (((__bytes) + (size_t)_ALIGN - 1)/(size_t)_ALIGN - 1); }
00370
00371
00372
00373
static void*
00374 _S_refill(size_t __n);
00375
00376
00377
00378
static char*
00379 _S_chunk_alloc(size_t __size,
int& __nobjs);
00380
00381
00382
00383
struct _Lock
00384 {
00385 _Lock() {
if (__threads) _S_node_allocator_lock._M_acquire_lock(); }
00386 ~_Lock() {
if (__threads) _S_node_allocator_lock._M_release_lock(); }
00387 } __attribute__ ((__unused__));
00388
friend struct _Lock;
00389
00390
static _Atomic_word _S_force_new;
00391
00392
public:
00393
00394
static void*
00395 allocate(size_t __n)
00396 {
00397
void* __ret = 0;
00398
00399
00400
00401
00402
if (_S_force_new == 0)
00403 {
00404
if (getenv(
"GLIBCPP_FORCE_NEW"))
00405 __atomic_add(&_S_force_new, 1);
00406
else
00407 __atomic_add(&_S_force_new, -1);
00408
00409 assert(_S_force_new != 0);
00410 }
00411
00412
if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
00413 __ret = __new_alloc::allocate(__n);
00414
else
00415 {
00416 _Obj*
volatile* __my_free_list = _S_free_list
00417 + _S_freelist_index(__n);
00418
00419
00420
00421 _Lock __lock_instance;
00422 _Obj* __restrict__ __result = *__my_free_list;
00423
if (__builtin_expect(__result == 0, 0))
00424 __ret = _S_refill(_S_round_up(__n));
00425
else
00426 {
00427 *__my_free_list = __result -> _M_free_list_link;
00428 __ret = __result;
00429 }
00430
if (__builtin_expect(__ret == 0, 0))
00431 __throw_bad_alloc();
00432 }
00433
return __ret;
00434 }
00435
00436
00437
static void
00438 deallocate(
void* __p, size_t __n)
00439 {
00440
if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
00441 __new_alloc::deallocate(__p, __n);
00442
else
00443 {
00444 _Obj*
volatile* __my_free_list = _S_free_list
00445 + _S_freelist_index(__n);
00446 _Obj* __q = (_Obj*)__p;
00447
00448
00449
00450
00451 _Lock __lock_instance;
00452 __q -> _M_free_list_link = *__my_free_list;
00453 *__my_free_list = __q;
00454 }
00455 }
00456
00457
00458
static void*
00459 reallocate(
void* __p, size_t __old_sz, size_t __new_sz);
00460 };
00461
00462
template<
bool __threads,
int __inst> _Atomic_word
00463
__default_alloc_template<__threads, __inst>::_S_force_new = 0;
00464
00465
template<
bool __threads,
int __inst>
00466
inline bool
00467
operator==(
const __default_alloc_template<__threads,__inst>&,
00468
const __default_alloc_template<__threads,__inst>&)
00469 {
return true; }
00470
00471
template<
bool __threads,
int __inst>
00472
inline bool
00473
operator!=(
const __default_alloc_template<__threads,__inst>&,
00474
const __default_alloc_template<__threads,__inst>&)
00475 {
return false; }
00476
00477
00478
00479
00480
00481
template<
bool __threads,
int __inst>
00482
char*
00483 __default_alloc_template<__threads, __inst>::
00484 _S_chunk_alloc(size_t __size,
int& __nobjs)
00485 {
00486
char* __result;
00487 size_t __total_bytes = __size * __nobjs;
00488 size_t __bytes_left = _S_end_free - _S_start_free;
00489
00490
if (__bytes_left >= __total_bytes)
00491 {
00492 __result = _S_start_free;
00493 _S_start_free += __total_bytes;
00494
return __result ;
00495 }
00496
else if (__bytes_left >= __size)
00497 {
00498 __nobjs = (
int)(__bytes_left/__size);
00499 __total_bytes = __size * __nobjs;
00500 __result = _S_start_free;
00501 _S_start_free += __total_bytes;
00502
return __result;
00503 }
00504
else
00505 {
00506 size_t __bytes_to_get =
00507 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
00508
00509
if (__bytes_left > 0)
00510 {
00511 _Obj*
volatile* __my_free_list =
00512 _S_free_list + _S_freelist_index(__bytes_left);
00513
00514 ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
00515 *__my_free_list = (_Obj*)_S_start_free;
00516 }
00517 _S_start_free = (
char*) __new_alloc::allocate(__bytes_to_get);
00518
if (_S_start_free == 0)
00519 {
00520 size_t __i;
00521 _Obj*
volatile* __my_free_list;
00522 _Obj* __p;
00523
00524
00525
00526 __i = __size;
00527
for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN)
00528 {
00529 __my_free_list = _S_free_list + _S_freelist_index(__i);
00530 __p = *__my_free_list;
00531
if (__p != 0)
00532 {
00533 *__my_free_list = __p -> _M_free_list_link;
00534 _S_start_free = (
char*)__p;
00535 _S_end_free = _S_start_free + __i;
00536
return _S_chunk_alloc(__size, __nobjs);
00537
00538
00539 }
00540 }
00541 _S_end_free = 0;
00542 _S_start_free = (
char*)__new_alloc::allocate(__bytes_to_get);
00543
00544
00545 }
00546 _S_heap_size += __bytes_to_get;
00547 _S_end_free = _S_start_free + __bytes_to_get;
00548
return _S_chunk_alloc(__size, __nobjs);
00549 }
00550 }
00551
00552
00553
00554
00555
00556
template<
bool __threads,
int __inst>
00557
void*
00558 __default_alloc_template<__threads, __inst>::_S_refill(size_t __n)
00559 {
00560
int __nobjs = 20;
00561
char* __chunk = _S_chunk_alloc(__n, __nobjs);
00562 _Obj*
volatile* __my_free_list;
00563 _Obj* __result;
00564 _Obj* __current_obj;
00565 _Obj* __next_obj;
00566
int __i;
00567
00568
if (1 == __nobjs)
00569
return __chunk;
00570 __my_free_list = _S_free_list + _S_freelist_index(__n);
00571
00572
00573 __result = (_Obj*)__chunk;
00574 *__my_free_list = __next_obj = (_Obj*)(__chunk + __n);
00575
for (__i = 1; ; __i++)
00576 {
00577 __current_obj = __next_obj;
00578 __next_obj = (_Obj*)((
char*)__next_obj + __n);
00579
if (__nobjs - 1 == __i)
00580 {
00581 __current_obj -> _M_free_list_link = 0;
00582
break;
00583 }
00584
else
00585 __current_obj -> _M_free_list_link = __next_obj;
00586 }
00587
return __result;
00588 }
00589
00590
00591
00592
template<
bool threads,
int inst>
00593
void*
00594 __default_alloc_template<threads, inst>::
00595 reallocate(
void* __p, size_t __old_sz, size_t __new_sz)
00596 {
00597
void* __result;
00598 size_t __copy_sz;
00599
00600
if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES)
00601
return(realloc(__p, __new_sz));
00602
if (_S_round_up(__old_sz) == _S_round_up(__new_sz))
00603
return(__p);
00604 __result = allocate(__new_sz);
00605 __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
00606 memcpy(__result, __p, __copy_sz);
00607 deallocate(__p, __old_sz);
00608
return __result;
00609 }
00610
00611
template<
bool __threads,
int __inst>
00612 _STL_mutex_lock
00613 __default_alloc_template<__threads,__inst>::_S_node_allocator_lock
00614 __STL_MUTEX_INITIALIZER;
00615
00616
template<
bool __threads,
int __inst>
00617
char* __default_alloc_template<__threads,__inst>::_S_start_free = 0;
00618
00619
template<
bool __threads,
int __inst>
00620
char* __default_alloc_template<__threads,__inst>::_S_end_free = 0;
00621
00622
template<
bool __threads,
int __inst>
00623 size_t __default_alloc_template<__threads,__inst>::_S_heap_size = 0;
00624
00625
template<
bool __threads,
int __inst>
00626
typename __default_alloc_template<__threads,__inst>::_Obj*
volatile
00627 __default_alloc_template<__threads,__inst>::_S_free_list[_NFREELISTS];
00628
00629
typedef __default_alloc_template<true,0> __alloc;
00630
typedef __default_alloc_template<false,0> __single_client_alloc;
00631
00632
00647
template<
typename _Tp>
00648 class allocator
00649 {
00650
typedef __alloc _Alloc;
00651
public:
00652
typedef size_t size_type;
00653
typedef ptrdiff_t difference_type;
00654
typedef _Tp* pointer;
00655
typedef const _Tp* const_pointer;
00656
typedef _Tp& reference;
00657
typedef const _Tp& const_reference;
00658
typedef _Tp value_type;
00659
00660
template<
typename _Tp1>
00661
struct rebind
00662 {
typedef allocator<_Tp1> other; };
00663
00664
allocator()
throw() {}
00665
allocator(
const allocator&)
throw() {}
00666
template<
typename _Tp1>
00667
allocator(
const allocator<_Tp1>&)
throw() {}
00668 ~
allocator()
throw() {}
00669
00670 pointer
00671 address(reference __x)
const {
return &__x; }
00672
00673 const_pointer
00674 address(const_reference __x)
const {
return &__x; }
00675
00676
00677
00678 _Tp*
00679 allocate(size_type __n,
const void* = 0)
00680 {
00681 _Tp* __ret = 0;
00682
if (__n)
00683 {
00684
if (__n <= this->max_size())
00685 __ret = static_cast<_Tp*>(_Alloc::allocate(__n *
sizeof(_Tp)));
00686
else
00687 __throw_bad_alloc();
00688 }
00689
return __ret;
00690 }
00691
00692
00693
void
00694 deallocate(pointer __p, size_type __n)
00695 { _Alloc::deallocate(__p, __n *
sizeof(_Tp)); }
00696
00697 size_type
00698 max_size()
const throw() {
return size_t(-1) /
sizeof(_Tp); }
00699
00700
void construct(pointer __p,
const _Tp& __val) {
new(__p) _Tp(__val); }
00701
void destroy(pointer __p) { __p->~_Tp(); }
00702 };
00703
00704
template<>
00705
class allocator<void>
00706 {
00707
public:
00708
typedef size_t size_type;
00709
typedef ptrdiff_t difference_type;
00710
typedef void* pointer;
00711
typedef const void* const_pointer;
00712
typedef void value_type;
00713
00714
template<
typename _Tp1>
00715
struct rebind
00716 {
typedef allocator<_Tp1> other; };
00717 };
00718
00719
00720
template<
typename _T1,
typename _T2>
00721
inline bool
00722
operator==(
const allocator<_T1>&,
const allocator<_T2>&)
00723 {
return true; }
00724
00725
template<
typename _T1,
typename _T2>
00726
inline bool
00727
operator!=(
const allocator<_T1>&,
const allocator<_T2>&)
00728 {
return false; }
00729
00730
00743
template<
typename _Tp,
typename _Alloc>
00744 struct __allocator
00745 {
00746 _Alloc __underlying_alloc;
00747
00748
typedef size_t size_type;
00749
typedef ptrdiff_t difference_type;
00750
typedef _Tp* pointer;
00751
typedef const _Tp* const_pointer;
00752
typedef _Tp& reference;
00753
typedef const _Tp& const_reference;
00754
typedef _Tp value_type;
00755
00756
template<
typename _Tp1>
00757
struct rebind
00758 {
typedef __allocator<_Tp1, _Alloc> other; };
00759
00760
__allocator()
throw() {}
00761
__allocator(
const __allocator& __a)
throw()
00762 : __underlying_alloc(__a.
__underlying_alloc) {}
00763
00764
template<
typename _Tp1>
00765
__allocator(
const __allocator<_Tp1, _Alloc>& __a)
throw()
00766 : __underlying_alloc(__a.
__underlying_alloc) {}
00767
00768 ~
__allocator()
throw() {}
00769
00770 pointer
00771 address(reference __x)
const {
return &__x; }
00772
00773 const_pointer
00774 address(const_reference __x)
const {
return &__x; }
00775
00776
00777
00778 _Tp*
00779 allocate(size_type __n,
const void* = 0)
00780 {
00781 _Tp* __ret = 0;
00782
if (__n)
00783 __ret = static_cast<_Tp*>(_Alloc::allocate(__n *
sizeof(_Tp)));
00784
return __ret;
00785 }
00786
00787
00788
void
00789 deallocate(pointer __p, size_type __n)
00790 { __underlying_alloc.deallocate(__p, __n *
sizeof(_Tp)); }
00791
00792 size_type
00793 max_size()
const throw() {
return size_t(-1) /
sizeof(_Tp); }
00794
00795
void
00796 construct(pointer __p,
const _Tp& __val) {
new(__p) _Tp(__val); }
00797
00798
void
00799 destroy(pointer __p) { __p->~_Tp(); }
00800 };
00801
00802
template<
typename _Alloc>
00803
struct __allocator<void, _Alloc>
00804 {
00805
typedef size_t size_type;
00806
typedef ptrdiff_t difference_type;
00807
typedef void* pointer;
00808
typedef const void* const_pointer;
00809
typedef void value_type;
00810
00811
template<
typename _Tp1>
00812
struct rebind
00813 {
typedef __allocator<_Tp1, _Alloc> other; };
00814 };
00815
00816
template<
typename _Tp,
typename _Alloc>
00817
inline bool
00818
operator==(
const __allocator<_Tp,_Alloc>& __a1,
00819
const __allocator<_Tp,_Alloc>& __a2)
00820 {
return __a1.__underlying_alloc == __a2.__underlying_alloc; }
00821
00822
template<
typename _Tp,
typename _Alloc>
00823
inline bool
00824
operator!=(
const __allocator<_Tp, _Alloc>& __a1,
00825
const __allocator<_Tp, _Alloc>& __a2)
00826 {
return __a1.__underlying_alloc != __a2.__underlying_alloc; }
00827
00828
00830
00834
template<
int inst>
00835
inline bool
00836 operator==(
const __malloc_alloc_template<inst>&,
00837
const __malloc_alloc_template<inst>&)
00838 {
return true; }
00839
00840
template<
int __inst>
00841
inline bool
00842 operator!=(
const __malloc_alloc_template<__inst>&,
00843
const __malloc_alloc_template<__inst>&)
00844 {
return false; }
00845
00846
template<
typename _Alloc>
00847
inline bool
00848 operator==(
const __debug_alloc<_Alloc>&,
const __debug_alloc<_Alloc>&)
00849 {
return true; }
00850
00851
template<
typename _Alloc>
00852
inline bool
00853 operator!=(
const __debug_alloc<_Alloc>&,
const __debug_alloc<_Alloc>&)
00854 {
return false; }
00856
00857
00895
00896
template<
typename _Tp,
typename _Allocator>
00897 struct _Alloc_traits
00898 {
00899
static const bool _S_instanceless =
false;
00900
typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
00901 };
00902
00903
template<
typename _Tp,
typename _Allocator>
00904
const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
00905
00907
template<
typename _Tp,
typename _Tp1>
00908 struct _Alloc_traits<_Tp, allocator<_Tp1> >
00909 {
00910
static const bool _S_instanceless =
true;
00911
typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
00912
typedef allocator<_Tp> allocator_type;
00913 };
00915
00917
00918
template<
typename _Tp,
int __inst>
00919 struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> >
00920 {
00921
static const bool _S_instanceless =
true;
00922
typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> >
_Alloc_type;
00923
typedef __allocator<_Tp, __malloc_alloc_template<__inst> >
allocator_type;
00924 };
00925
00926
template<
typename _Tp,
bool __threads,
int __inst>
00927
struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
00928 {
00929
static const bool _S_instanceless =
true;
00930
typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> >
00931 _Alloc_type;
00932
typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
00933 allocator_type;
00934 };
00935
00936
template<
typename _Tp,
typename _Alloc>
00937
struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
00938 {
00939
static const bool _S_instanceless =
true;
00940
typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
00941
typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
00942 };
00944
00946
00947
00948
template<
typename _Tp,
typename _Tp1,
int __inst>
00949 struct _Alloc_traits<_Tp,
00950 __allocator<_Tp1, __malloc_alloc_template<__inst> > >
00951 {
00952
static const bool _S_instanceless =
true;
00953
typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> >
_Alloc_type;
00954
typedef __allocator<_Tp, __malloc_alloc_template<__inst> >
allocator_type;
00955 };
00956
00957
template<
typename _Tp,
typename _Tp1,
bool __thr,
int __inst>
00958
struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > >
00959 {
00960
static const bool _S_instanceless =
true;
00961
typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> >
00962 _Alloc_type;
00963
typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
00964 allocator_type;
00965 };
00966
00967
template<
typename _Tp,
typename _Tp1,
typename _Alloc>
00968
struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
00969 {
00970
static const bool _S_instanceless =
true;
00971
typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
00972
typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
00973 };
00975
00976
00977
00978
00979
extern template class allocator<char>;
00980
extern template class allocator<wchar_t>;
00981
extern template class __default_alloc_template<true,0>;
00982 }
00983
00984
#endif