/home/ntakagi/work/STLport-5.1.5/stlport/stl/_alloc.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 1996,1997
00004  * Silicon Graphics Computer Systems, Inc.
00005  *
00006  * Copyright (c) 1997
00007  * Moscow Center for SPARC Technology
00008  *
00009  * Copyright (c) 1999
00010  * Boris Fomitchev
00011  *
00012  * This material is provided "as is", with absolutely no warranty expressed
00013  * or implied. Any use is at your own risk.
00014  *
00015  * Permission to use or copy this software for any purpose is hereby granted
00016  * without fee, provided the above notices are retained on all copies.
00017  * Permission to modify the code and to distribute modified code is granted,
00018  * provided the above notices are retained, and a notice that the code was
00019  * modified is included with the above copyright notice.
00020  *
00021  */
00022 
00023 /* NOTE: This is an internal header file, included by other STL headers.
00024  *   You should not attempt to use it directly.
00025  */
00026 
00027 #ifndef _STLP_INTERNAL_ALLOC_H
00028 #define _STLP_INTERNAL_ALLOC_H
00029 
00030 #ifndef _STLP_INTERNAL_CSTDDEF
00031 #  include <stl/_cstddef.h>
00032 #endif
00033 
00034 #if !defined (_STLP_DEBUG_H) && (defined(_STLP_DEBUG) || defined(_STLP_ASSERTIONS) || defined(_STLP_DEBUG_ALLOC))
00035 #  include <stl/debug/_debug.h>
00036 #endif
00037 
00038 #ifndef _STLP_INTERNAL_CSTDLIB
00039 #  include <stl/_cstdlib.h>
00040 #endif
00041 
00042 #ifndef _STLP_INTERNAL_CSTRING
00043 #  include <stl/_cstring.h>
00044 #endif
00045 
00046 #ifndef _STLP_INTERNAL_ALGOBASE_H
00047 #  include <stl/_algobase.h>
00048 #endif
00049 
00050 #ifndef __THROW_BAD_ALLOC
00051 #  if !defined(_STLP_USE_EXCEPTIONS)
00052 #    ifndef _STLP_INTERNAL_CSTDIO
00053 #      include <stl/_cstdio.h>
00054 #    endif
00055 #    define __THROW_BAD_ALLOC puts("out of memory\n"); exit(1)
00056 #  else
00057 #    define __THROW_BAD_ALLOC throw _STLP_STD::bad_alloc()
00058 #  endif
00059 #endif
00060 
00061 #ifndef _STLP_INTERNAL_NEW_HEADER
00062 #  include <stl/_new.h>
00063 #endif
00064 
00065 #ifndef _STLP_INTERNAL_CONSTRUCT_H
00066 #  include <stl/_construct.h>
00067 #endif
00068 
00069 #if !defined (__ALLOC)
00070 #  define __ALLOC __sgi_alloc
00071 #endif
00072 
00073 _STLP_BEGIN_NAMESPACE
00074 
00075 #if defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00076 template <class _Tp, class _Alloc> struct __allocator;
00077 #endif
00078 
00079 // Malloc-based allocator.  Typically slower than default alloc below.
00080 // Typically thread-safe and more storage efficient.
00081 
00082 #if !defined (_STLP_USE_NO_IOSTREAMS)
00083 typedef void (* __oom_handler_type)();
00084 #endif
00085 
00086 class _STLP_CLASS_DECLSPEC __malloc_alloc {
00087 public:
00088   // this one is needed for proper simple_alloc wrapping
00089   typedef char value_type;
00090 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00091   template <class _Tp1> struct rebind {
00092     typedef __allocator<_Tp1, __malloc_alloc> other;
00093   };
00094 #endif
00095   static void* _STLP_CALL allocate(size_t& __n)
00096 #if !defined (_STLP_USE_NO_IOSTREAMS)
00097   ;
00098 #else
00099   {
00100     void *__result = malloc(__n);
00101 #  if defined (_STLP_MALLOC_USABLE_SIZE)
00102     if (__result != 0) {
00103       __n = _STLP_MALLOC_USABLE_SIZE(__result);
00104     }
00105 #  endif
00106     if (__result == 0) {
00107       __THROW_BAD_ALLOC;
00108     }
00109     return __result;
00110   }
00111 #endif
00112 
00113   static void _STLP_CALL deallocate(void* __p, size_t /* __n */) { free((char*)__p); }
00114 #if !defined (_STLP_USE_NO_IOSTREAMS)
00115   static __oom_handler_type _STLP_CALL set_malloc_handler(__oom_handler_type __f);
00116 #endif
00117 };
00118 
00119 // New-based allocator.  Typically slower than default alloc below.
00120 // Typically thread-safe and more storage efficient.
00121 class _STLP_CLASS_DECLSPEC __new_alloc {
00122 public:
00123   // this one is needed for proper simple_alloc wrapping
00124   typedef char value_type;
00125 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00126   template <class _Tp1> struct rebind {
00127     typedef __allocator<_Tp1, __new_alloc > other;
00128   };
00129 #endif
00130   static void* _STLP_CALL allocate(size_t __n) { return __stl_new(__n); }
00131   static void _STLP_CALL deallocate(void* __p, size_t) { __stl_delete(__p); }
00132 };
00133 
00134 
00135 // Allocator adaptor to check size arguments for debugging.
00136 // Reports errors using assert.  Checking can be disabled with
00137 // NDEBUG, but it's far better to just use the underlying allocator
00138 // instead when no checking is desired.
00139 // There is some evidence that this can confuse Purify.
00140 // This adaptor can only be applied to raw allocators
00141 
00142 template <class _Alloc>
00143 class __debug_alloc : public _Alloc {
00144 public:
00145   typedef _Alloc __allocator_type;
00146   typedef typename _Alloc::value_type value_type;
00147 private:
00148   struct __alloc_header {
00149     size_t __magic: 16;
00150     size_t __type_size:16;
00151     _STLP_UINT32_T _M_size;
00152   }; // that is 8 bytes for sure
00153   // Sunpro CC has bug on enums, so extra_before/after set explicitly
00154   enum { __pad = 8, __magic = 0xdeba, __deleted_magic = 0xdebd,
00155          __shred_byte = _STLP_SHRED_BYTE };
00156 
00157   enum { __extra_before = 16, __extra_after = 8 };
00158   // Size of space used to store size.  Note
00159   // that this must be large enough to preserve
00160   // alignment.
00161   static size_t _STLP_CALL __extra_before_chunk() {
00162     return (long)__extra_before / sizeof(value_type) +
00163       (size_t)((long)__extra_before % sizeof(value_type) > 0);
00164   }
00165   static size_t _STLP_CALL __extra_after_chunk() {
00166     return (long)__extra_after / sizeof(value_type) +
00167       (size_t)((long)__extra_after % sizeof(value_type) > 0);
00168   }
00169 public:
00170 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00171   template <class _Tp1> struct rebind {
00172     typedef __allocator< _Tp1, __debug_alloc<_Alloc> > other;
00173   };
00174 #endif
00175   __debug_alloc() {}
00176   ~__debug_alloc() {}
00177   static void* _STLP_CALL allocate(size_t);
00178   static void _STLP_CALL deallocate(void *, size_t);
00179 };
00180 
00181 #  if defined (__OS400__) || defined (_WIN64)
00182 enum {_ALIGN = 16, _ALIGN_SHIFT = 4, _MAX_BYTES = 256};
00183 #  else
00184 enum {_ALIGN = 8, _ALIGN_SHIFT = 3, _MAX_BYTES = 128};
00185 #  endif /* __OS400__ */
00186 
00187 #if !defined (_STLP_USE_NO_IOSTREAMS)
00188 // Default node allocator.
00189 // With a reasonable compiler, this should be roughly as fast as the
00190 // original STL class-specific allocators, but with less fragmentation.
00191 class _STLP_CLASS_DECLSPEC __node_alloc {
00192   static void * _STLP_CALL _M_allocate(size_t& __n);
00193   /* __p may not be 0 */
00194   static void _STLP_CALL _M_deallocate(void *__p, size_t __n);
00195 
00196 public:
00197   // this one is needed for proper simple_alloc wrapping
00198   typedef char value_type;
00199 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00200   template <class _Tp1> struct rebind {
00201     typedef __allocator<_Tp1, __node_alloc> other;
00202   };
00203 #  endif
00204   /* __n must be > 0      */
00205   static void* _STLP_CALL allocate(size_t& __n)
00206   { return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); }
00207   /* __p may not be 0 */
00208   static void _STLP_CALL deallocate(void *__p, size_t __n)
00209   { if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); }
00210 };
00211 
00212 #  if defined (_STLP_USE_TEMPLATE_EXPORT)
00213 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__node_alloc>;
00214 #  endif
00215 
00216 #endif /* _STLP_USE_NO_IOSTREAMS */
00217 
00218 #if defined (_STLP_USE_TEMPLATE_EXPORT)
00219 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__new_alloc>;
00220 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__malloc_alloc>;
00221 #endif
00222 
00223 /* macro to convert the allocator for initialization
00224  * not using MEMBER_TEMPLATE_CLASSES as it should work given template constructor  */
00225 #if defined (_STLP_MEMBER_TEMPLATES) || ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00226 /* if _STLP_NO_TEMPLATE_CONVERSIONS is set, the member template constructor is
00227  * not used implicitly to convert allocator parameter, so let us do it explicitly */
00228 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_NO_TEMPLATE_CONVERSIONS)
00229 #    define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
00230 #  else
00231 #    define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __a
00232 #  endif
00233 /* else convert, but only if partial specialization works, since else
00234  * Container::allocator_type won't be different */
00235 #else
00236 #  define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
00237 #endif /* _STLP_MEMBER_TEMPLATES || !_STLP_CLASS_PARTIAL_SPECIALIZATION */
00238 
00239 // Another allocator adaptor: _Alloc_traits.  This serves two
00240 // purposes.  First, make it possible to write containers that can use
00241 // either SGI-style allocators or standard-conforming allocator.
00242 
00243 // The fully general version.
00244 template <class _Tp, class _Allocator>
00245 struct _Alloc_traits {
00246   typedef _Allocator _Orig;
00247 #if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
00248   typedef typename _Allocator::_STLP_TEMPLATE rebind<_Tp> _Rebind_type;
00249   typedef typename _Rebind_type::other  allocator_type;
00250   static allocator_type create_allocator(const _Orig& __a)
00251   { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); }
00252 #else
00253   // this is not actually true, used only to pass this type through
00254   // to dynamic overload selection in _STLP_alloc_proxy methods
00255   typedef _Allocator allocator_type;
00256 #endif /* !_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
00257 };
00258 
00259 #if defined (_STLP_USE_PERTHREAD_ALLOC)
00260 
00261 _STLP_END_NAMESPACE
00262 
00263 // include additional header here
00264 #  include <stl/_pthread_alloc.h>
00265 
00266 _STLP_BEGIN_NAMESPACE
00267 
00268 #  if defined (_STLP_DEBUG_ALLOC)
00269 typedef __debug_alloc<__pthread_alloc> __sgi_alloc;
00270 #  else
00271 typedef __pthread_alloc __sgi_alloc;
00272 #  endif /* _STLP_DEBUG_ALLOC */
00273 
00274 typedef __pthread_alloc __single_client_alloc;
00275 typedef __pthread_alloc __multithreaded_alloc;
00276 
00277 #else /* _STLP_USE_PERTHREAD_ALLOC */
00278 
00279 #  if defined (_STLP_USE_NEWALLOC)
00280 
00281 #    if defined (_STLP_DEBUG_ALLOC)
00282 typedef __debug_alloc<__new_alloc> __sgi_alloc;
00283 #    else
00284 typedef __new_alloc __sgi_alloc;
00285 #    endif /* _STLP_DEBUG_ALLOC */
00286 
00287 typedef __new_alloc __single_client_alloc;
00288 typedef __new_alloc __multithreaded_alloc;
00289 
00290 #  elif defined (_STLP_USE_MALLOC)
00291 
00292 #    if defined (_STLP_DEBUG_ALLOC)
00293 typedef __debug_alloc<__malloc_alloc> __sgi_alloc;
00294 #    else
00295 typedef __malloc_alloc __sgi_alloc;
00296 #    endif /* _STLP_DEBUG_ALLOC */
00297 
00298 typedef __malloc_alloc __single_client_alloc;
00299 typedef __malloc_alloc __multithreaded_alloc;
00300 
00301 #  else
00302 
00303 #    if defined (_STLP_DEBUG_ALLOC)
00304 typedef __debug_alloc<__node_alloc> __sgi_alloc;
00305 #    else
00306 typedef __node_alloc __sgi_alloc;
00307 #    endif
00308 
00309 typedef __node_alloc __single_client_alloc;
00310 typedef __node_alloc __multithreaded_alloc;
00311 
00312 #  endif /* _STLP_USE_NEWALLOC */
00313 #endif /* _STLP_USE_PERTHREAD_ALLOC */
00314 
00315 // This implements allocators as specified in the C++ standard.
00316 //
00317 // Note that standard-conforming allocators use many language features
00318 // that are not yet widely implemented.  In particular, they rely on
00319 // member templates, partial specialization, partial ordering of function
00320 // templates, the typename keyword, and the use of the template keyword
00321 // to refer to a template member of a dependent type.
00322 
00323 /*
00324 template <class _Tp>
00325 struct _AllocatorAux {
00326   typedef _Tp*       pointer;
00327   typedef const _Tp* const_pointer;
00328   typedef _Tp&       reference;
00329   typedef const _Tp& const_reference;
00330 
00331   pointer address(reference __x) const {return &__x;}
00332   const_pointer address(const_reference __x) const { return &__x; }
00333 };
00334 
00335 template <class _Tp>
00336 struct _AllocatorAux<const _Tp> {
00337   typedef _Tp*       pointer;
00338   typedef const _Tp* const_pointer;
00339   typedef _Tp&       reference;
00340   typedef const _Tp& const_reference;
00341 
00342   const_pointer address(const_reference __x) const { return &__x; }
00343 };
00344 */
00345 
00346 template <class _Tp>
00347 class allocator //: public _AllocatorAux<_Tp>
00348 /* A small helper struct to recognize STLport allocator implementation
00349  * from any user specialization one.
00350  */
00351                 : public __stlport_class<allocator<_Tp> > {
00352 public:
00353   typedef _Tp        value_type;
00354   typedef _Tp*       pointer;
00355   typedef const _Tp* const_pointer;
00356   typedef _Tp&       reference;
00357   typedef const _Tp& const_reference;
00358   typedef size_t     size_type;
00359   typedef ptrdiff_t  difference_type;
00360 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00361   template <class _Tp1> struct rebind {
00362     typedef allocator<_Tp1> other;
00363   };
00364 #endif
00365   allocator() _STLP_NOTHROW {}
00366 #if defined (_STLP_MEMBER_TEMPLATES)
00367   template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
00368 #endif
00369   allocator(const allocator<_Tp>&) _STLP_NOTHROW {}
00370   allocator(__move_source<allocator<_Tp> > src) _STLP_NOTHROW {}
00371   ~allocator() _STLP_NOTHROW {}
00372   pointer address(reference __x) const {return &__x;}
00373   const_pointer address(const_reference __x) const { return &__x; }
00374   // __n is permitted to be 0.  The C++ standard says nothing about what the return value is when __n == 0.
00375   _Tp* allocate(size_type __n, const void* = 0) {
00376     if (__n > max_size()) {
00377       __THROW_BAD_ALLOC;
00378     }
00379     if (__n != 0) {
00380       size_type __buf_size = __n * sizeof(value_type);
00381       _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
00382 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00383       if (__ret != 0) {
00384         memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
00385       }
00386 #endif
00387       return __ret;
00388     }
00389     else
00390       return 0;
00391   }
00392   // __p is permitted to be a null pointer, only if n==0.
00393   void deallocate(pointer __p, size_type __n) {
00394     _STLP_ASSERT( (__p == 0) == (__n == 0) )
00395     if (__p != 0) {
00396 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00397       memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
00398 #endif
00399       __sgi_alloc::deallocate((void*)__p, __n * sizeof(value_type));
00400     }
00401   }
00402   // backwards compatibility
00403   void deallocate(pointer __p) const {  if (__p != 0) __sgi_alloc::deallocate((void*)__p, sizeof(value_type)); }
00404   size_type max_size() const _STLP_NOTHROW  { return size_t(-1) / sizeof(value_type); }
00405   void construct(pointer __p, const_reference __val) { _STLP_STD::_Copy_Construct(__p, __val); }
00406   void destroy(pointer __p) { _STLP_STD::_Destroy(__p); }
00407 #if defined(__MRC__)||(defined(__SC__) && !defined(__DMC__))
00408   template <class _T2> bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; }
00409   template <class _T2> bool operator!=(const allocator<_T2>&) const _STLP_NOTHROW { return false; }
00410 #endif
00411 
00412 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
00413   //This is just to make swap workaround for compiler without template function partial
00414   //happy.
00415   void swap(allocator<_Tp>&) {}
00416 #endif
00417 
00418 #if defined (_STLP_NO_EXTENSIONS)
00419   /* STLport extension giving rounded size of an allocated memory buffer
00420    * This method do not have to be part of a user defined allocator implementation
00421    * and won't even be called if such a function was granted.
00422    */
00423 protected:
00424 #endif
00425   _Tp* allocate(size_type __n, size_type& __allocated_n) {
00426     if (__n > max_size()) {
00427       __THROW_BAD_ALLOC;
00428     }
00429 
00430     if (__n != 0) {
00431       size_type __buf_size = __n * sizeof(value_type);
00432       _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
00433 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00434       if (__ret != 0) {
00435         memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
00436       }
00437 #endif
00438       __allocated_n = __buf_size / sizeof(value_type);
00439       return __ret;
00440     }
00441     else
00442       return 0;
00443   }
00444 };
00445 
00446 _STLP_TEMPLATE_NULL
00447 class _STLP_CLASS_DECLSPEC allocator<void> {
00448 public:
00449   typedef size_t      size_type;
00450   typedef ptrdiff_t   difference_type;
00451   typedef void*       pointer;
00452   typedef const void* const_pointer;
00453 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00454   typedef void        value_type;
00455 #endif
00456 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00457   template <class _Tp1> struct rebind {
00458     typedef allocator<_Tp1> other;
00459   };
00460 #endif
00461 #if defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__))  //*ty 03/24/2001 - MPW compilers get confused on these operator definitions
00462   template <class _T2> bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; }
00463   template <class _T2> bool operator!=(const allocator<_T2>&) const _STLP_NOTHROW { return false; }
00464 #endif
00465 };
00466 
00467 #if !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__)))  //*ty 03/24/2001 - MPW compilers get confused on these operator definitions
00468 template <class _T1, class _T2> inline bool  _STLP_CALL operator==(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW { return true; }
00469 template <class _T1, class _T2> inline bool  _STLP_CALL operator!=(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW { return false; }
00470 #endif
00471 
00472 #if defined (_STLP_USE_TEMPLATE_EXPORT)
00473 _STLP_EXPORT_TEMPLATE_CLASS allocator<char>;
00474 #  if defined (_STLP_HAS_WCHAR_T)
00475 _STLP_EXPORT_TEMPLATE_CLASS allocator<wchar_t>;
00476 #  endif
00477 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00478 _STLP_EXPORT_TEMPLATE_CLASS allocator<void*>;
00479 #  endif
00480 #endif
00481 
00482 _STLP_MOVE_TO_PRIV_NAMESPACE
00483 
00484 template <class _Tp>
00485 struct __alloc_type_traits {
00486 #if !defined (__BORLANDC__)
00487   typedef typename _IsSTLportClass<allocator<_Tp> >::_Ret _STLportAlloc;
00488 #else
00489   enum { _Is = _IsSTLportClass<allocator<_Tp> >::_Is };
00490   typedef typename __bool2type<_Is>::_Ret _STLportAlloc;
00491 #endif
00492   //The default allocator implementation which is recognize thanks to the
00493   //__stlport_class inheritance is a stateless object so:
00494   typedef _STLportAlloc has_trivial_default_constructor;
00495   typedef _STLportAlloc has_trivial_copy_constructor;
00496   typedef _STLportAlloc has_trivial_assignment_operator;
00497   typedef _STLportAlloc has_trivial_destructor;
00498   typedef _STLportAlloc is_POD_type;
00499 };
00500 
00501 _STLP_MOVE_TO_STD_NAMESPACE
00502 
00503 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00504 template <class _Tp>
00505 struct __type_traits<allocator<_Tp> > : _STLP_PRIV __alloc_type_traits<_Tp> {};
00506 #else
00507 _STLP_TEMPLATE_NULL
00508 struct __type_traits<allocator<char> > : _STLP_PRIV __alloc_type_traits<char> {};
00509 #  if defined (_STLP_HAS_WCHAR_T)
00510 _STLP_TEMPLATE_NULL
00511 struct __type_traits<allocator<wchar_t> > : _STLP_PRIV __alloc_type_traits<wchar_t> {};
00512 #  endif
00513 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00514 _STLP_TEMPLATE_NULL
00515 struct __type_traits<allocator<void*> > : _STLP_PRIV __alloc_type_traits<void*> {};
00516 #  endif
00517 #endif
00518 
00519 
00520 #if !defined (_STLP_FORCE_ALLOCATORS)
00521 #  define _STLP_FORCE_ALLOCATORS(a,y)
00522 #endif
00523 
00524 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00525 // The version for the default allocator, for rare occasion when we have partial spec w/o member template classes
00526 template <class _Tp, class _Tp1>
00527 struct _Alloc_traits<_Tp, allocator<_Tp1> > {
00528   typedef allocator<_Tp1> _Orig;
00529   typedef allocator<_Tp> allocator_type;
00530   static allocator_type create_allocator(const allocator<_Tp1 >& __a)
00531   { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); }
00532 };
00533 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00534 
00535 #if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) && defined (_STLP_MEMBER_TEMPLATES)
00536 template <class _Tp, class _Alloc>
00537 inline _STLP_TYPENAME_ON_RETURN_TYPE _Alloc_traits<_Tp, _Alloc>::allocator_type  _STLP_CALL
00538 __stl_alloc_create(const _Alloc& __a, const _Tp*) {
00539   typedef typename _Alloc::_STLP_TEMPLATE rebind<_Tp>::other _Rebound_type;
00540   return _Rebound_type(__a);
00541 }
00542 #else
00543 // If custom allocators are being used without member template classes support :
00544 // user (on purpose) is forced to define rebind/get operations !!!
00545 template <class _Tp1, class _Tp2>
00546 inline allocator<_Tp2>& _STLP_CALL
00547 __stl_alloc_rebind(allocator<_Tp1>& __a, const _Tp2*) {  return (allocator<_Tp2>&)(__a); }
00548 template <class _Tp1, class _Tp2>
00549 inline allocator<_Tp2> _STLP_CALL
00550 __stl_alloc_create(const allocator<_Tp1>&, const _Tp2*) { return allocator<_Tp2>(); }
00551 #endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
00552 
00553 #if defined (_STLP_USE_RAW_SGI_ALLOCATORS)
00554 // move obsolete stuff out of the way
00555 #  include <stl/_alloc_old.h>
00556 #endif
00557 
00558 _STLP_MOVE_TO_PRIV_NAMESPACE
00559 
00560 // inheritance is being used for EBO optimization
00561 template <class _Value, class _Tp, class _MaybeReboundAlloc>
00562 class _STLP_alloc_proxy : public _MaybeReboundAlloc {
00563 private:
00564   typedef _MaybeReboundAlloc _Base;
00565   typedef typename _Base::size_type size_type;
00566   typedef _STLP_alloc_proxy<_Value, _Tp, _MaybeReboundAlloc> _Self;
00567 public:
00568   _Value _M_data;
00569 
00570   _STLP_alloc_proxy (const _MaybeReboundAlloc& __a, _Value __p) :
00571     _MaybeReboundAlloc(__a), _M_data(__p) {}
00572 
00573   _STLP_alloc_proxy (__move_source<_Self> src) :
00574     _MaybeReboundAlloc(_STLP_PRIV _AsMoveSource<_Base>(src.get())),
00575     _M_data(_STLP_PRIV _AsMoveSource<_Value>(src.get()._M_data)) {}
00576 
00577 private:
00578   /* Following are helper methods to detect stateless allocators and avoid
00579    * swap in this case. For some compilers (VC6) it is a workaround for a
00580    * compiler bug in the Empty Base class Optimization feature, for others
00581    * it is a small optimization or nothing if no EBO. */
00582   void _M_swap_alloc(_Self&, const __true_type& /*_IsStateless*/)
00583   {}
00584 
00585   void _M_swap_alloc(_Self& __x, const __false_type& /*_IsStateless*/) {
00586     _MaybeReboundAlloc &__base_this = *this;
00587     _MaybeReboundAlloc &__base_x = __x;
00588     _STLP_STD::swap(__base_this, __base_x);
00589   }
00590 
00591 public:
00592   void _M_swap_alloc(_Self& __x) {
00593 #if !defined (__BORLANDC__)
00594     typedef typename _IsStateless<_MaybeReboundAlloc>::_Ret _StatelessAlloc;
00595 #else
00596     typedef typename __bool2type<_IsStateless<_MaybeReboundAlloc>::_Is>::_Ret _StatelessAlloc;
00597 #endif
00598     _M_swap_alloc(__x, _StatelessAlloc());
00599   }
00600 
00601   /* We need to define the following swap implementation for allocator with state
00602    * as those allocators might have implement a special swap function to correctly
00603    * move datas from an instance to the oher, _STLP_alloc_proxy should not break
00604    * this mecanism. */
00605   void swap(_Self& __x) {
00606     _M_swap_alloc(__x);
00607     _STLP_STD::swap(_M_data, __x._M_data);
00608   }
00609 
00610   _Tp* allocate(size_type __n, size_type& __allocated_n) {
00611 #if !defined (__BORLANDC__)
00612     typedef typename _IsSTLportClass<_MaybeReboundAlloc>::_Ret _STLportAlloc;
00613 #else
00614     typedef typename __bool2type<_IsSTLportClass<_MaybeReboundAlloc>::_Is>::_Ret _STLportAlloc;
00615 #endif
00616     return allocate(__n, __allocated_n, _STLportAlloc());
00617   }
00618 
00619   // Unified interface to perform allocate()/deallocate() with limited
00620   // language support
00621 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
00622   // else it is rebound already, and allocate() member is accessible
00623   _Tp* allocate(size_type __n)
00624   { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, 0); }
00625   void deallocate(_Tp* __p, size_type __n)
00626   { __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).deallocate(__p, __n); }
00627 private:
00628   _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
00629   { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, __allocated_n); }
00630 #else
00631   //Expose Standard allocate overload (using expression do not work for some compilers (Borland))
00632   _Tp* allocate(size_type __n)
00633   { return _Base::allocate(__n); }
00634 private:
00635   _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
00636   { return _Base::allocate(__n, __allocated_n); }
00637 #endif
00638 
00639   _Tp* allocate(size_type __n, size_type& __allocated_n, const __false_type& /*STLport allocator*/)
00640   { __allocated_n = __n; return allocate(__n); }
00641 };
00642 
00643 #if defined (_STLP_USE_TEMPLATE_EXPORT)
00644 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<char*, char, allocator<char> >;
00645 #  if defined (_STLP_HAS_WCHAR_T)
00646 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<wchar_t*, wchar_t, allocator<wchar_t> >;
00647 #  endif
00648 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00649 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<void**, void*, allocator<void*> >;
00650 #  endif
00651 #endif
00652 
00653 _STLP_MOVE_TO_STD_NAMESPACE
00654 _STLP_END_NAMESPACE
00655 
00656 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
00657 #  include <stl/_alloc.c>
00658 #endif
00659 
00660 #endif /* _STLP_INTERNAL_ALLOC_H */
00661 
00662 // Local Variables:
00663 // mode:C++
00664 // End:
00665 



Generated on Mon Mar 10 15:32:18 2008 by  doxygen 1.5.1