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 #ifndef _STLP_INTERNAL_ALLOC_H
00028 #define _STLP_INTERNAL_ALLOC_H
00029
00030 # ifndef _STLP_CSTDDEF
00031 # include <cstddef>
00032 # endif
00033
00034 #if !defined (_STLP_DEBUG_H) && (defined (_STLP_DEBUG) || defined (_STLP_ASSERTIONS))
00035 # include <stl/debug/_debug.h>
00036 #endif
00037
00038 # ifndef _STLP_CSTDLIB
00039 # include <cstdlib>
00040 # endif
00041 # ifndef _STLP_CSTRING
00042 # include <cstring>
00043 # endif
00044
00045 # ifndef __THROW_BAD_ALLOC
00046 # if !defined(_STLP_USE_EXCEPTIONS)
00047 # if !defined (_STLP_CSTDIO)
00048 # include <cstdio>
00049 # endif
00050 # if !defined (_STLP_CSTDLIB)
00051 # include <cstdlib>
00052 # endif
00053 # define __THROW_BAD_ALLOC puts("out of memory\n"); exit(1)
00054 # else
00055 # define __THROW_BAD_ALLOC throw _STLP_STD::bad_alloc()
00056 # endif
00057 # endif
00058
00059 # ifndef _STLP_NEW_HEADER
00060 # include <new>
00061 # endif
00062
00063 #if ! defined (_STLP_INTERNAL_THREADS_H)
00064 # include <stl/_threads.h>
00065 #endif
00066
00067 #ifndef _STLP_INTERNAL_CONSTRUCT_H
00068 # include <stl/_construct.h>
00069 #endif
00070
00071 #ifndef __ALLOC
00072 # define __ALLOC __sgi_alloc
00073 #endif
00074
00075 # ifndef __RESTRICT
00076 # define __RESTRICT
00077 # endif
00078
00079 #if defined (_STLP_THREADS) || (defined(_STLP_OWN_IOSTREAMS) && ! defined (_STLP_NO_THREADS) && ! defined (_NOTHREADS) )
00080 # define _STLP_NODE_ALLOCATOR_THREADS true
00081 #else
00082 # define _STLP_NODE_ALLOCATOR_THREADS false
00083 #endif
00084
00085 _STLP_BEGIN_NAMESPACE
00086
00087 # if defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00088 template <class _Tp, class _Alloc> struct __allocator;
00089 # endif
00090
00091
00092
00093
00094 typedef void (* __oom_handler_type)();
00095
00096 template <int __inst>
00097 class __malloc_alloc {
00098 private:
00099 static void* _STLP_CALL _S_oom_malloc(size_t);
00100 static __oom_handler_type __oom_handler;
00101 public:
00102
00103 typedef char value_type;
00104 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00105 template <class _Tp1> struct rebind {
00106 typedef __allocator<_Tp1, __malloc_alloc<__inst> > other;
00107 };
00108 # endif
00109 static void* _STLP_CALL allocate(size_t __n) {
00110 void* __result = malloc(__n);
00111 if (0 == __result) __result = _S_oom_malloc(__n);
00112 return __result;
00113 }
00114 static void _STLP_CALL deallocate(void* __p, size_t ) { free((char*)__p); }
00115 static __oom_handler_type _STLP_CALL set_malloc_handler(__oom_handler_type __f) {
00116 __oom_handler_type __old = __oom_handler;
00117 __oom_handler = __f;
00118 return(__old);
00119 }
00120 };
00121
00122
00123
00124
00125 class _STLP_CLASS_DECLSPEC __new_alloc {
00126 public:
00127
00128 typedef char value_type;
00129 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined(_STLP_USE_RAW_SGI_ALLOCATORS)
00130 template <class _Tp1> struct rebind {
00131 typedef __allocator<_Tp1, __new_alloc > other;
00132 };
00133 # endif
00134 static void* _STLP_CALL allocate(size_t __n) { return __stl_new(__n); }
00135 static void _STLP_CALL deallocate(void* __p, size_t) { __stl_delete(__p); }
00136 };
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 template <class _Alloc>
00147 class __debug_alloc : public _Alloc {
00148 public:
00149 typedef _Alloc __allocator_type;
00150 typedef typename _Alloc::value_type value_type;
00151 private:
00152 struct __alloc_header {
00153 size_t __magic: 16;
00154 size_t __type_size:16;
00155 _STLP_UINT32_T _M_size;
00156 };
00157
00158 enum { __pad=8, __magic=0xdeba, __deleted_magic = 0xdebd,
00159 __shred_byte= _STLP_SHRED_BYTE
00160 };
00161
00162 enum { __extra_before = 16, __extra_after = 8 };
00163
00164
00165
00166 static size_t _STLP_CALL __extra_before_chunk() {
00167 return (long)__extra_before/sizeof(value_type)+
00168 (size_t)((long)__extra_before%sizeof(value_type)>0);
00169 }
00170 static size_t _STLP_CALL __extra_after_chunk() {
00171 return (long)__extra_after/sizeof(value_type)+
00172 (size_t)((long)__extra_after%sizeof(value_type)>0);
00173 }
00174 public:
00175 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00176 template <class _Tp1> struct rebind {
00177 typedef __allocator< _Tp1, __debug_alloc<_Alloc> > other;
00178 };
00179 # endif
00180 __debug_alloc() {}
00181 ~__debug_alloc() {}
00182 static void * _STLP_CALL allocate(size_t);
00183 static void _STLP_CALL deallocate(void *, size_t);
00184 };
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 # if defined(__OS400__)
00211 enum {_ALIGN = 16, _ALIGN_SHIFT=4, _MAX_BYTES = 256};
00212 # define _STLP_NFREELISTS 16
00213 # else
00214 enum {_ALIGN = 8, _ALIGN_SHIFT=3, _MAX_BYTES = 128};
00215 # define _STLP_NFREELISTS 16
00216 # endif
00217
00218 class _STLP_CLASS_DECLSPEC _Node_alloc_obj {
00219 public:
00220 _Node_alloc_obj * _M_free_list_link;
00221 };
00222
00223 template <bool __threads, int __inst>
00224 class __node_alloc {
00225 _STLP_PRIVATE:
00226 static inline size_t _STLP_CALL _S_round_up(size_t __bytes) { return (((__bytes) + (size_t)_ALIGN-1) & ~((size_t)_ALIGN - 1)); }
00227 typedef _Node_alloc_obj _Obj;
00228 private:
00229
00230 static void* _STLP_CALL _S_refill(size_t __n);
00231
00232
00233 static char* _STLP_CALL _S_chunk_alloc(size_t __p_size, int& __nobjs);
00234
00235 static _Node_alloc_obj * _STLP_VOLATILE _S_free_list[_STLP_NFREELISTS];
00236 static char* _S_start_free;
00237 static char* _S_end_free;
00238 static size_t _S_heap_size;
00239 static void * _STLP_CALL _M_allocate(size_t __n);
00240
00241 static void _STLP_CALL _M_deallocate(void *__p, size_t __n);
00242 public:
00243
00244 typedef char value_type;
00245 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00246 template <class _Tp1> struct rebind {
00247 typedef __allocator<_Tp1, __node_alloc<__threads, __inst> > other;
00248 };
00249 # endif
00250
00251 static void * _STLP_CALL allocate(size_t __n) { return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); }
00252
00253 static void _STLP_CALL deallocate(void *__p, size_t __n) { if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); }
00254 };
00255
00256 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00257 _STLP_EXPORT_TEMPLATE_CLASS __malloc_alloc<0>;
00258 _STLP_EXPORT_TEMPLATE_CLASS __node_alloc<_STLP_NODE_ALLOCATOR_THREADS, 0>;
00259 # endif
00260 typedef __node_alloc<_STLP_NODE_ALLOCATOR_THREADS, 0> _Node_alloc;
00261 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00262 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<_Node_alloc>;
00263 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__new_alloc>;
00264 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__malloc_alloc<0> >;
00265 # endif
00266
00267 # if defined (_STLP_USE_PERTHREAD_ALLOC)
00268
00269 _STLP_END_NAMESPACE
00270
00271 # include <stl/_pthread_alloc.h>
00272 _STLP_BEGIN_NAMESPACE
00273
00274 # if defined ( _STLP_DEBUG_ALLOC )
00275 typedef __debug_alloc<__pthread_alloc> __sgi_alloc;
00276 # else
00277 typedef __pthread_alloc __sgi_alloc;
00278 # endif
00279
00280 typedef __pthread_alloc __single_client_alloc;
00281 typedef __pthread_alloc __multithreaded_alloc;
00282
00283 # else
00284
00285 # if defined ( _STLP_USE_NEWALLOC )
00286
00287 # if defined ( _STLP_DEBUG_ALLOC )
00288 typedef __debug_alloc<__new_alloc> __sgi_alloc;
00289 # else
00290 typedef __new_alloc __sgi_alloc;
00291 # endif
00292
00293 typedef __new_alloc __single_client_alloc;
00294 typedef __new_alloc __multithreaded_alloc;
00295
00296 # elif defined (_STLP_USE_MALLOC)
00297
00298 # if defined ( _STLP_DEBUG_ALLOC )
00299 typedef __debug_alloc<__malloc_alloc<0> > __sgi_alloc;
00300 # else
00301 typedef __malloc_alloc<0> __sgi_alloc;
00302 # endif
00303
00304 typedef __malloc_alloc<0> __single_client_alloc;
00305 typedef __malloc_alloc<0> __multithreaded_alloc;
00306
00307 # else
00308
00309 # if defined ( _STLP_DEBUG_ALLOC )
00310 typedef __debug_alloc<_Node_alloc> __sgi_alloc;
00311 # else
00312 typedef _Node_alloc __sgi_alloc;
00313 # endif
00314
00315 typedef __node_alloc<false, 0> __single_client_alloc;
00316 typedef __node_alloc<true, 0> __multithreaded_alloc;
00317
00318 # endif
00319 # endif
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 template <class _Tp>
00330 class allocator {
00331 public:
00332
00333 typedef _Tp value_type;
00334 typedef value_type * pointer;
00335 typedef const _Tp* const_pointer;
00336 typedef _Tp& reference;
00337 typedef const _Tp& const_reference;
00338 typedef size_t size_type;
00339 typedef ptrdiff_t difference_type;
00340 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00341 template <class _Tp1> struct rebind {
00342 typedef allocator<_Tp1> other;
00343 };
00344 # endif
00345 allocator() _STLP_NOTHROW {}
00346 # if defined (_STLP_MEMBER_TEMPLATES)
00347 template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
00348 # endif
00349 allocator(const allocator<_Tp>&) _STLP_NOTHROW {}
00350 ~allocator() _STLP_NOTHROW {}
00351 pointer address(reference __x) { return &__x; }
00352 const_pointer address(const_reference __x) const { return &__x; }
00353
00354 _Tp* allocate(size_type __n, const void* = 0) const {
00355 return __n != 0 ? __REINTERPRET_CAST(value_type*,__sgi_alloc::allocate(__n * sizeof(value_type))) : 0;
00356 }
00357
00358 void deallocate(pointer __p, size_type __n) const {
00359 _STLP_ASSERT( (__p == 0) == (__n == 0) )
00360 if (__p != 0) __sgi_alloc::deallocate((void*)__p, __n * sizeof(value_type));
00361 }
00362
00363 void deallocate(pointer __p) const { if (__p != 0) __sgi_alloc::deallocate((void*)__p, sizeof(value_type)); }
00364 size_type max_size() const _STLP_NOTHROW { return size_t(-1) / sizeof(value_type); }
00365 void construct(pointer __p, const _Tp& __val) const { _STLP_STD::_Construct(__p, __val); }
00366 void destroy(pointer __p) const { _STLP_STD::_Destroy(__p); }
00367 # if defined(__MRC__)||defined(__SC__)
00368 template <class _T2> bool operator==(const allocator<_T2>&) const { return true; }
00369 template <class _T2> bool operator!=(const allocator<_T2>&) const { return false; }
00370 # endif
00371 };
00372
00373 _STLP_TEMPLATE_NULL
00374 class _STLP_CLASS_DECLSPEC allocator<void> {
00375 public:
00376 typedef size_t size_type;
00377 typedef ptrdiff_t difference_type;
00378 typedef void* pointer;
00379 typedef const void* const_pointer;
00380 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00381 typedef void value_type;
00382 # endif
00383 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00384 template <class _Tp1> struct rebind {
00385 typedef allocator<_Tp1> other;
00386 };
00387 # endif
00388 # if defined(__MRC__)||defined(__SC__) //*ty 03/24/2001 - MPW compilers get confused on these operator definitions
00389 template <class _T2> bool operator==(const allocator<_T2>&) const { return true; }
00390 template <class _T2> bool operator!=(const allocator<_T2>&) const { return false; }
00391 # endif
00392 };
00393
00394 #if !(defined(__MRC__)||defined(__SC__)) //*ty 03/24/2001 - MPW compilers get confused on these operator definitions
00395 template <class _T1, class _T2> inline bool _STLP_CALL operator==(const allocator<_T1>&, const allocator<_T2>&) { return true; }
00396 template <class _T1, class _T2> inline bool _STLP_CALL operator!=(const allocator<_T1>&, const allocator<_T2>&) { return false; }
00397 #endif
00398
00399 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00400 _STLP_EXPORT_TEMPLATE_CLASS allocator<char>;
00401 # if defined (_STLP_HAS_WCHAR_T)
00402 _STLP_EXPORT_TEMPLATE_CLASS allocator<wchar_t>;
00403 # endif
00404 # endif
00405
00406
00407
00408
00409
00410
00411 template <class _Tp, class _Allocator>
00412 struct _Alloc_traits
00413 {
00414 typedef _Allocator _Orig;
00415 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00416 typedef typename _Allocator::_STLP_TEMPLATE rebind<_Tp> _Rebind_type;
00417 typedef typename _Rebind_type::other allocator_type;
00418 static allocator_type create_allocator(const _Orig& __a) { return allocator_type(__a); }
00419 # else
00420
00421
00422 typedef _Allocator allocator_type;
00423 # endif
00424 };
00425
00426 #ifndef _STLP_FORCE_ALLOCATORS
00427 #define _STLP_FORCE_ALLOCATORS(a,y)
00428 #endif
00429
00430 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && ! defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00431
00432 template <class _Tp, class _Tp1>
00433 struct _Alloc_traits<_Tp, allocator<_Tp1> > {
00434 typedef allocator<_Tp1> _Orig;
00435 typedef allocator<_Tp> allocator_type;
00436 static allocator_type create_allocator(const allocator<_Tp1 >& __a) { return allocator_type(__a); }
00437 };
00438 #endif
00439
00440
00441
00442 #if defined (_STLP_MEMBER_TEMPLATES) || ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00443
00444
00445 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_NO_TEMPLATE_CONVERSIONS)
00446 # define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
00447 # else
00448 # define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __a
00449 # endif
00450
00451
00452 #else
00453 # define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
00454 #endif
00455
00456 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00457 template <class _Tp, class _Alloc>
00458 inline _STLP_TYPENAME_ON_RETURN_TYPE _Alloc_traits<_Tp, _Alloc>::allocator_type _STLP_CALL
00459 __stl_alloc_create(const _Alloc& __a, const _Tp*) {
00460 typedef typename _Alloc::_STLP_TEMPLATE rebind<_Tp>::other _Rebound_type;
00461 return _Rebound_type(__a);
00462 }
00463 #else
00464
00465
00466 template <class _Tp1, class _Tp2>
00467 inline allocator<_Tp2>& _STLP_CALL
00468 __stl_alloc_rebind(allocator<_Tp1>& __a, const _Tp2*) { return (allocator<_Tp2>&)(__a); }
00469 template <class _Tp1, class _Tp2>
00470 inline allocator<_Tp2> _STLP_CALL
00471 __stl_alloc_create(const allocator<_Tp1>&, const _Tp2*) { return allocator<_Tp2>(); }
00472 #endif
00473
00474 # ifdef _STLP_USE_RAW_SGI_ALLOCATORS
00475
00476 # include <stl/_alloc_old.h>
00477 # endif
00478
00479
00480 template <class _Value, class _Tp, class _MaybeReboundAlloc>
00481 class _STLP_alloc_proxy : public _MaybeReboundAlloc {
00482 private:
00483 typedef _MaybeReboundAlloc _Base;
00484 typedef _STLP_alloc_proxy<_Value, _Tp, _MaybeReboundAlloc> _Self;
00485 public:
00486 _Value _M_data;
00487
00488 inline _STLP_alloc_proxy(const _Self& __x) : _MaybeReboundAlloc(__x), _M_data(__x._M_data) {}
00489 inline _STLP_alloc_proxy(const _MaybeReboundAlloc& __a, _Value __p) : _MaybeReboundAlloc(__a), _M_data(__p) {}
00490 inline _Self& operator = (const _Self& __x) { _M_data = __x._M_data; return *this; }
00491 inline _Self& operator = (const _Base& __x) { ((_Base&)*this) = __x; return *this; }
00492
00493
00494 #if ! defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00495
00496 inline _Tp* allocate(size_t __n) {
00497 return __stl_alloc_rebind(__STATIC_CAST(_Base&,*this),(_Tp*)0).allocate(__n,0);
00498 }
00499 inline void deallocate(_Tp* __p, size_t __n) {
00500 __stl_alloc_rebind(__STATIC_CAST(_Base&, *this),(_Tp*)0).deallocate(__p, __n);
00501 }
00502 #endif
00503 };
00504
00505 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00506 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<char *,char,allocator<char> >;
00507 # if defined (_STLP_HAS_WCHAR_T)
00508 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<wchar_t *,wchar_t,allocator<wchar_t> >;
00509 # endif
00510 # endif
00511
00512 # undef _STLP_NODE_ALLOCATOR_THREADS
00513
00514 _STLP_END_NAMESPACE
00515
00516 # if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
00517 # include <stl/_alloc.c>
00518 # endif
00519
00520 #endif
00521
00522
00523
00524
00525