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
00043
00044
00045
00046
00047
00048 #ifndef __GLIBCPP_INTERNAL_ALLOC_H
00049 #define __GLIBCPP_INTERNAL_ALLOC_H
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #include <cstddef>
00086 #include <cstdlib>
00087 #include <cstring>
00088 #include <bits/functexcept.h>
00089 #include <bits/stl_threads.h>
00090
00091 #include <bits/atomicity.h>
00092
00093 namespace std
00094 {
00095
00096
00097
00098
00099
00100
00101
00102
00103 class __new_alloc
00104 {
00105 public:
00106 static void*
00107 allocate(size_t __n)
00108 { return ::operator new(__n); }
00109
00110 static void
00111 deallocate(void* __p, size_t)
00112 { ::operator delete(__p); }
00113 };
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 template<int __inst>
00127 class __malloc_alloc_template
00128 {
00129 private:
00130 static void* _S_oom_malloc(size_t);
00131 static void* _S_oom_realloc(void*, size_t);
00132 static void (* __malloc_alloc_oom_handler)();
00133
00134 public:
00135 static void*
00136 allocate(size_t __n)
00137 {
00138 void* __result = malloc(__n);
00139 if (__builtin_expect(__result == 0, 0))
00140 __result = _S_oom_malloc(__n);
00141 return __result;
00142 }
00143
00144 static void
00145 deallocate(void* __p, size_t )
00146 { free(__p); }
00147
00148 static void*
00149 reallocate(void* __p, size_t , size_t __new_sz)
00150 {
00151 void* __result = realloc(__p, __new_sz);
00152 if (__builtin_expect(__result == 0, 0))
00153 __result = _S_oom_realloc(__p, __new_sz);
00154 return __result;
00155 }
00156
00157 static void (* __set_malloc_handler(void (*__f)()))()
00158 {
00159 void (* __old)() = __malloc_alloc_oom_handler;
00160 __malloc_alloc_oom_handler = __f;
00161 return __old;
00162 }
00163 };
00164
00165
00166 template<int __inst>
00167 void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;
00168
00169 template<int __inst>
00170 void*
00171 __malloc_alloc_template<__inst>::
00172 _S_oom_malloc(size_t __n)
00173 {
00174 void (* __my_malloc_handler)();
00175 void* __result;
00176
00177 for (;;)
00178 {
00179 __my_malloc_handler = __malloc_alloc_oom_handler;
00180 if (__builtin_expect(__my_malloc_handler == 0, 0))
00181 __throw_bad_alloc();
00182 (*__my_malloc_handler)();
00183 __result = malloc(__n);
00184 if (__result)
00185 return __result;
00186 }
00187 }
00188
00189 template<int __inst>
00190 void*
00191 __malloc_alloc_template<__inst>::
00192 _S_oom_realloc(void* __p, size_t __n)
00193 {
00194 void (* __my_malloc_handler)();
00195 void* __result;
00196
00197 for (;;)
00198 {
00199 __my_malloc_handler = __malloc_alloc_oom_handler;
00200 if (__builtin_expect(__my_malloc_handler == 0, 0))
00201 __throw_bad_alloc();
00202 (*__my_malloc_handler)();
00203 __result = realloc(__p, __n);
00204 if (__result)
00205 return __result;
00206 }
00207 }
00208
00209
00210 typedef __new_alloc __mem_interface;
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 template<typename _Tp, typename _Alloc>
00224 class __simple_alloc
00225 {
00226 public:
00227 static _Tp*
00228 allocate(size_t __n)
00229 {
00230 _Tp* __ret = 0;
00231 if (__n)
00232 __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
00233 return __ret;
00234 }
00235
00236 static _Tp*
00237 allocate()
00238 { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
00239
00240 static void
00241 deallocate(_Tp* __p, size_t __n)
00242 { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
00243
00244 static void
00245 deallocate(_Tp* __p)
00246 { _Alloc::deallocate(__p, sizeof (_Tp)); }
00247 };
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 template<typename _Alloc>
00262 class __debug_alloc
00263 {
00264 private:
00265
00266
00267 enum {_S_extra = 8};
00268
00269 public:
00270 static void*
00271 allocate(size_t __n)
00272 {
00273 char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
00274 *(size_t*)__result = __n;
00275 return __result + (int) _S_extra;
00276 }
00277
00278 static void
00279 deallocate(void* __p, size_t __n)
00280 {
00281 char* __real_p = (char*)__p - (int) _S_extra;
00282 if (*(size_t*)__real_p != __n)
00283 abort();
00284 _Alloc::deallocate(__real_p, __n + (int) _S_extra);
00285 }
00286
00287 static void*
00288 reallocate(void* __p, size_t __old_sz, size_t __new_sz)
00289 {
00290 char* __real_p = (char*)__p - (int) _S_extra;
00291 if (*(size_t*)__real_p != __old_sz)
00292 abort();
00293 char* __result = (char*) _Alloc::reallocate(__real_p,
00294 __old_sz + (int) _S_extra,
00295 __new_sz + (int) _S_extra);
00296 *(size_t*)__result = __new_sz;
00297 return __result + (int) _S_extra;
00298 }
00299 };
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 template<bool __threads, int __inst>
00333 class __default_alloc_template
00334 {
00335 private:
00336 enum {_ALIGN = 8};
00337 enum {_MAX_BYTES = 128};
00338 enum {_NFREELISTS = _MAX_BYTES / _ALIGN};
00339
00340 union _Obj
00341 {
00342 union _Obj* _M_free_list_link;
00343 char _M_client_data[1];
00344 };
00345
00346 static _Obj* volatile _S_free_list[_NFREELISTS];
00347
00348
00349 static char* _S_start_free;
00350 static char* _S_end_free;
00351 static size_t _S_heap_size;
00352
00353 static _STL_mutex_lock _S_node_allocator_lock;
00354
00355 static size_t
00356 _S_round_up(size_t __bytes)
00357 { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }
00358
00359 static size_t
00360 _S_freelist_index(size_t __bytes)
00361 { return (((__bytes) + (size_t)_ALIGN - 1)/(size_t)_ALIGN - 1); }
00362
00363
00364
00365 static void*
00366 _S_refill(size_t __n);
00367
00368
00369
00370 static char*
00371 _S_chunk_alloc(size_t __size, int& __nobjs);
00372
00373
00374
00375 struct _Lock
00376 {
00377 _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); }
00378 ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); }
00379 } __attribute__ ((__unused__));
00380 friend struct _Lock;
00381
00382 static _Atomic_word _S_force_new;
00383
00384 public:
00385
00386 static void*
00387 allocate(size_t __n)
00388 {
00389 void* __ret = 0;
00390
00391
00392
00393
00394 if (_S_force_new == 0)
00395 {
00396 if (getenv("GLIBCPP_FORCE_NEW"))
00397 __atomic_add(&_S_force_new, 1);
00398 else
00399 __atomic_add(&_S_force_new, -1);
00400 }
00401
00402 if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
00403 __ret = __new_alloc::allocate(__n);
00404 else
00405 {
00406 _Obj* volatile* __my_free_list = _S_free_list
00407 + _S_freelist_index(__n);
00408
00409
00410
00411 _Lock __lock_instance;
00412 _Obj* __restrict__ __result = *__my_free_list;
00413 if (__builtin_expect(__result == 0, 0))
00414 __ret = _S_refill(_S_round_up(__n));
00415 else
00416 {
00417 *__my_free_list = __result -> _M_free_list_link;
00418 __ret = __result;
00419 }
00420 if (__builtin_expect(__ret == 0, 0))
00421 __throw_bad_alloc();
00422 }
00423 return __ret;
00424 }
00425
00426
00427 static void
00428 deallocate(void* __p, size_t __n)
00429 {
00430 if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
00431 __new_alloc::deallocate(__p, __n);
00432 else
00433 {
00434 _Obj* volatile* __my_free_list = _S_free_list
00435 + _S_freelist_index(__n);
00436 _Obj* __q = (_Obj*)__p;
00437
00438
00439
00440
00441 _Lock __lock_instance;
00442 __q -> _M_free_list_link = *__my_free_list;
00443 *__my_free_list = __q;
00444 }
00445 }
00446
00447 static void*
00448 reallocate(void* __p, size_t __old_sz, size_t __new_sz);
00449 };
00450
00451 template<bool __threads, int __inst> _Atomic_word
00452 __default_alloc_template<__threads, __inst>::_S_force_new = 0;
00453
00454 template<bool __threads, int __inst>
00455 inline bool
00456 operator==(const __default_alloc_template<__threads,__inst>&,
00457 const __default_alloc_template<__threads,__inst>&)
00458 { return true; }
00459
00460 template<bool __threads, int __inst>
00461 inline bool
00462 operator!=(const __default_alloc_template<__threads,__inst>&,
00463 const __default_alloc_template<__threads,__inst>&)
00464 { return false; }
00465
00466
00467
00468
00469
00470 template<bool __threads, int __inst>
00471 char*
00472 __default_alloc_template<__threads, __inst>::
00473 _S_chunk_alloc(size_t __size, int& __nobjs)
00474 {
00475 char* __result;
00476 size_t __total_bytes = __size * __nobjs;
00477 size_t __bytes_left = _S_end_free - _S_start_free;
00478
00479 if (__bytes_left >= __total_bytes)
00480 {
00481 __result = _S_start_free;
00482 _S_start_free += __total_bytes;
00483 return __result ;
00484 }
00485 else if (__bytes_left >= __size)
00486 {
00487 __nobjs = (int)(__bytes_left/__size);
00488 __total_bytes = __size * __nobjs;
00489 __result = _S_start_free;
00490 _S_start_free += __total_bytes;
00491 return __result;
00492 }
00493 else
00494 {
00495 size_t __bytes_to_get =
00496 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
00497
00498 if (__bytes_left > 0)
00499 {
00500 _Obj* volatile* __my_free_list =
00501 _S_free_list + _S_freelist_index(__bytes_left);
00502
00503 ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list;
00504 *__my_free_list = (_Obj*)(void*)_S_start_free;
00505 }
00506 _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
00507 if (_S_start_free == 0)
00508 {
00509 size_t __i;
00510 _Obj* volatile* __my_free_list;
00511 _Obj* __p;
00512
00513
00514
00515 __i = __size;
00516 for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN)
00517 {
00518 __my_free_list = _S_free_list + _S_freelist_index(__i);
00519 __p = *__my_free_list;
00520 if (__p != 0)
00521 {
00522 *__my_free_list = __p -> _M_free_list_link;
00523 _S_start_free = (char*)__p;
00524 _S_end_free = _S_start_free + __i;
00525 return _S_chunk_alloc(__size, __nobjs);
00526
00527
00528 }
00529 }
00530 _S_end_free = 0;
00531 _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
00532
00533
00534 }
00535 _S_heap_size += __bytes_to_get;
00536 _S_end_free = _S_start_free + __bytes_to_get;
00537 return _S_chunk_alloc(__size, __nobjs);
00538 }
00539 }
00540
00541
00542
00543
00544
00545 template<bool __threads, int __inst>
00546 void*
00547 __default_alloc_template<__threads, __inst>::_S_refill(size_t __n)
00548 {
00549 int __nobjs = 20;
00550 char* __chunk = _S_chunk_alloc(__n, __nobjs);
00551 _Obj* volatile* __my_free_list;
00552 _Obj* __result;
00553 _Obj* __current_obj;
00554 _Obj* __next_obj;
00555 int __i;
00556
00557 if (1 == __nobjs)
00558 return __chunk;
00559 __my_free_list = _S_free_list + _S_freelist_index(__n);
00560
00561
00562 __result = (_Obj*)(void*)__chunk;
00563 *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
00564 for (__i = 1; ; __i++)
00565 {
00566 __current_obj = __next_obj;
00567 __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
00568 if (__nobjs - 1 == __i)
00569 {
00570 __current_obj -> _M_free_list_link = 0;
00571 break;
00572 }
00573 else
00574 __current_obj -> _M_free_list_link = __next_obj;
00575 }
00576 return __result;
00577 }
00578
00579
00580 template<bool threads, int inst>
00581 void*
00582 __default_alloc_template<threads, inst>::
00583 reallocate(void* __p, size_t __old_sz, size_t __new_sz)
00584 {
00585 void* __result;
00586 size_t __copy_sz;
00587
00588 if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES)
00589 return(realloc(__p, __new_sz));
00590 if (_S_round_up(__old_sz) == _S_round_up(__new_sz))
00591 return(__p);
00592 __result = allocate(__new_sz);
00593 __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
00594 memcpy(__result, __p, __copy_sz);
00595 deallocate(__p, __old_sz);
00596 return __result;
00597 }
00598
00599 template<bool __threads, int __inst>
00600 _STL_mutex_lock
00601 __default_alloc_template<__threads,__inst>::_S_node_allocator_lock
00602 __STL_MUTEX_INITIALIZER;
00603
00604 template<bool __threads, int __inst>
00605 char* __default_alloc_template<__threads,__inst>::_S_start_free = 0;
00606
00607 template<bool __threads, int __inst>
00608 char* __default_alloc_template<__threads,__inst>::_S_end_free = 0;
00609
00610 template<bool __threads, int __inst>
00611 size_t __default_alloc_template<__threads,__inst>::_S_heap_size = 0;
00612
00613 template<bool __threads, int __inst>
00614 typename __default_alloc_template<__threads,__inst>::_Obj* volatile
00615 __default_alloc_template<__threads,__inst>::_S_free_list[_NFREELISTS];
00616
00617 typedef __default_alloc_template<true,0> __alloc;
00618 typedef __default_alloc_template<false,0> __single_client_alloc;
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 template<typename _Tp>
00636 class allocator
00637 {
00638 typedef __alloc _Alloc;
00639 public:
00640 typedef size_t size_type;
00641 typedef ptrdiff_t difference_type;
00642 typedef _Tp* pointer;
00643 typedef const _Tp* const_pointer;
00644 typedef _Tp& reference;
00645 typedef const _Tp& const_reference;
00646 typedef _Tp value_type;
00647
00648 template<typename _Tp1>
00649 struct rebind
00650 { typedef allocator<_Tp1> other; };
00651
00652 allocator() throw() {}
00653 allocator(const allocator&) throw() {}
00654 template<typename _Tp1>
00655 allocator(const allocator<_Tp1>&) throw() {}
00656 ~allocator() throw() {}
00657
00658 pointer
00659 address(reference __x) const { return &__x; }
00660
00661 const_pointer
00662 address(const_reference __x) const { return &__x; }
00663
00664
00665
00666 _Tp*
00667 allocate(size_type __n, const void* = 0)
00668 {
00669 _Tp* __ret = 0;
00670 if (__n)
00671 {
00672 if (__n <= this->max_size())
00673 __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
00674 else
00675 __throw_bad_alloc();
00676 }
00677 return __ret;
00678 }
00679
00680
00681 void
00682 deallocate(pointer __p, size_type __n)
00683 { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
00684
00685 size_type
00686 max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
00687
00688 void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
00689 void destroy(pointer __p) { __p->~_Tp(); }
00690 };
00691
00692 template<>
00693 class allocator<void>
00694 {
00695 public:
00696 typedef size_t size_type;
00697 typedef ptrdiff_t difference_type;
00698 typedef void* pointer;
00699 typedef const void* const_pointer;
00700 typedef void value_type;
00701
00702 template<typename _Tp1>
00703 struct rebind
00704 { typedef allocator<_Tp1> other; };
00705 };
00706
00707
00708 template<typename _T1, typename _T2>
00709 inline bool
00710 operator==(const allocator<_T1>&, const allocator<_T2>&)
00711 { return true; }
00712
00713 template<typename _T1, typename _T2>
00714 inline bool
00715 operator!=(const allocator<_T1>&, const allocator<_T2>&)
00716 { return false; }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 template<typename _Tp, typename _Alloc>
00732 struct __allocator
00733 {
00734 _Alloc __underlying_alloc;
00735
00736 typedef size_t size_type;
00737 typedef ptrdiff_t difference_type;
00738 typedef _Tp* pointer;
00739 typedef const _Tp* const_pointer;
00740 typedef _Tp& reference;
00741 typedef const _Tp& const_reference;
00742 typedef _Tp value_type;
00743
00744 template<typename _Tp1>
00745 struct rebind
00746 { typedef __allocator<_Tp1, _Alloc> other; };
00747
00748 __allocator() throw() {}
00749 __allocator(const __allocator& __a) throw()
00750 : __underlying_alloc(__a.__underlying_alloc) {}
00751
00752 template<typename _Tp1>
00753 __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
00754 : __underlying_alloc(__a.__underlying_alloc) {}
00755
00756 ~__allocator() throw() {}
00757
00758 pointer
00759 address(reference __x) const { return &__x; }
00760
00761 const_pointer
00762 address(const_reference __x) const { return &__x; }
00763
00764
00765
00766 _Tp*
00767 allocate(size_type __n, const void* = 0)
00768 {
00769 _Tp* __ret = 0;
00770 if (__n)
00771 __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
00772 return __ret;
00773 }
00774
00775
00776 void
00777 deallocate(pointer __p, size_type __n)
00778 { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
00779
00780 size_type
00781 max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
00782
00783 void
00784 construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
00785
00786 void
00787 destroy(pointer __p) { __p->~_Tp(); }
00788 };
00789
00790 template<typename _Alloc>
00791 struct __allocator<void, _Alloc>
00792 {
00793 typedef size_t size_type;
00794 typedef ptrdiff_t difference_type;
00795 typedef void* pointer;
00796 typedef const void* const_pointer;
00797 typedef void value_type;
00798
00799 template<typename _Tp1>
00800 struct rebind
00801 { typedef __allocator<_Tp1, _Alloc> other; };
00802 };
00803
00804 template<typename _Tp, typename _Alloc>
00805 inline bool
00806 operator==(const __allocator<_Tp,_Alloc>& __a1,
00807 const __allocator<_Tp,_Alloc>& __a2)
00808 { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
00809
00810 template<typename _Tp, typename _Alloc>
00811 inline bool
00812 operator!=(const __allocator<_Tp, _Alloc>& __a1,
00813 const __allocator<_Tp, _Alloc>& __a2)
00814 { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
00815
00816
00817
00818
00819
00820
00821
00822 template<int inst>
00823 inline bool
00824 operator==(const __malloc_alloc_template<inst>&,
00825 const __malloc_alloc_template<inst>&)
00826 { return true; }
00827
00828 template<int __inst>
00829 inline bool
00830 operator!=(const __malloc_alloc_template<__inst>&,
00831 const __malloc_alloc_template<__inst>&)
00832 { return false; }
00833
00834 template<typename _Alloc>
00835 inline bool
00836 operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
00837 { return true; }
00838
00839 template<typename _Alloc>
00840 inline bool
00841 operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
00842 { return false; }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884 template<typename _Tp, typename _Allocator>
00885 struct _Alloc_traits
00886 {
00887 static const bool _S_instanceless = false;
00888 typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
00889 };
00890
00891 template<typename _Tp, typename _Allocator>
00892 const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
00893
00894
00895 template<typename _Tp, typename _Tp1>
00896 struct _Alloc_traits<_Tp, allocator<_Tp1> >
00897 {
00898 static const bool _S_instanceless = true;
00899 typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
00900 typedef allocator<_Tp> allocator_type;
00901 };
00902
00903
00904
00905
00906 template<typename _Tp, int __inst>
00907 struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> >
00908 {
00909 static const bool _S_instanceless = true;
00910 typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
00911 typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
00912 };
00913
00914 template<typename _Tp, bool __threads, int __inst>
00915 struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
00916 {
00917 static const bool _S_instanceless = true;
00918 typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> >
00919 _Alloc_type;
00920 typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
00921 allocator_type;
00922 };
00923
00924 template<typename _Tp, typename _Alloc>
00925 struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
00926 {
00927 static const bool _S_instanceless = true;
00928 typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
00929 typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
00930 };
00931
00932
00933
00934
00935
00936 template<typename _Tp, typename _Tp1, int __inst>
00937 struct _Alloc_traits<_Tp,
00938 __allocator<_Tp1, __malloc_alloc_template<__inst> > >
00939 {
00940 static const bool _S_instanceless = true;
00941 typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
00942 typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
00943 };
00944
00945 template<typename _Tp, typename _Tp1, bool __thr, int __inst>
00946 struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > >
00947 {
00948 static const bool _S_instanceless = true;
00949 typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> >
00950 _Alloc_type;
00951 typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
00952 allocator_type;
00953 };
00954
00955 template<typename _Tp, typename _Tp1, typename _Alloc>
00956 struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
00957 {
00958 static const bool _S_instanceless = true;
00959 typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
00960 typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
00961 };
00962
00963
00964
00965
00966
00967 #if _GLIBCPP_EXTERN_TEMPLATE
00968 extern template class allocator<char>;
00969 extern template class allocator<wchar_t>;
00970 extern template class __default_alloc_template<true,0>;
00971 #endif
00972 }
00973
00974 #endif