Home | History | Annotate | Download | only in stl
      1 /*
      2  *
      3  * Copyright (c) 1996,1997
      4  * Silicon Graphics Computer Systems, Inc.
      5  *
      6  * Copyright (c) 1997
      7  * Moscow Center for SPARC Technology
      8  *
      9  * Copyright (c) 1999
     10  * Boris Fomitchev
     11  *
     12  * This material is provided "as is", with absolutely no warranty expressed
     13  * or implied. Any use is at your own risk.
     14  *
     15  * Permission to use or copy this software for any purpose is hereby granted
     16  * without fee, provided the above notices are retained on all copies.
     17  * Permission to modify the code and to distribute modified code is granted,
     18  * provided the above notices are retained, and a notice that the code was
     19  * modified is included with the above copyright notice.
     20  *
     21  */
     22 
     23 /* NOTE: This is an internal header file, included by other STL headers.
     24  *   You should not attempt to use it directly.
     25  */
     26 
     27 #ifndef _STLP_INTERNAL_ALLOC_H
     28 #define _STLP_INTERNAL_ALLOC_H
     29 
     30 #ifndef _STLP_INTERNAL_CSTDDEF
     31 #  include <stl/_cstddef.h>
     32 #endif
     33 
     34 #ifndef _STLP_INTERNAL_CSTDLIB
     35 #  include <stl/_cstdlib.h>
     36 #endif
     37 
     38 #ifndef _STLP_INTERNAL_CSTRING
     39 #  include <stl/_cstring.h>
     40 #endif
     41 
     42 #ifndef _STLP_INTERNAL_ALGOBASE_H
     43 #  include <stl/_algobase.h>
     44 #endif
     45 
     46 #ifndef _STLP_INTERNAL_NEW_HEADER
     47 #  include <stl/_new.h>
     48 #endif
     49 
     50 #ifndef _STLP_INTERNAL_CONSTRUCT_H
     51 #  include <stl/_construct.h>
     52 #endif
     53 
     54 _STLP_BEGIN_NAMESPACE
     55 
     56 // Malloc-based allocator.  Typically slower than default alloc below.
     57 // Typically thread-safe and more storage efficient.
     58 
     59 #if !defined (_STLP_USE_NO_IOSTREAMS)
     60 typedef void (* __oom_handler_type)();
     61 #endif
     62 
     63 class _STLP_CLASS_DECLSPEC __malloc_alloc {
     64 public:
     65   // this one is needed for proper simple_alloc wrapping
     66   typedef char value_type;
     67   static void* _STLP_CALL allocate(size_t __n)
     68 #if !defined (_STLP_USE_NO_IOSTREAMS)
     69   ;
     70 #else
     71   {
     72     void *__result = malloc(__n);
     73     if (__result == 0) {
     74       _STLP_THROW_BAD_ALLOC;
     75     }
     76     return __result;
     77   }
     78 #endif
     79 
     80   static void _STLP_CALL deallocate(void* __p, size_t /* __n */) { free((char*)__p); }
     81 #if !defined (_STLP_USE_NO_IOSTREAMS)
     82   static __oom_handler_type _STLP_CALL set_malloc_handler(__oom_handler_type __f);
     83 #endif
     84 };
     85 
     86 // New-based allocator.  Typically slower than default alloc below.
     87 // Typically thread-safe and more storage efficient.
     88 class _STLP_CLASS_DECLSPEC __new_alloc {
     89 public:
     90   // this one is needed for proper simple_alloc wrapping
     91   typedef char value_type;
     92   static void* _STLP_CALL allocate(size_t __n) { return __stl_new(__n); }
     93   static void _STLP_CALL deallocate(void* __p, size_t) { __stl_delete(__p); }
     94 };
     95 
     96 // Allocator adaptor to check size arguments for debugging.
     97 // Reports errors using assert.  Checking can be disabled with
     98 // NDEBUG, but it's far better to just use the underlying allocator
     99 // instead when no checking is desired.
    100 // There is some evidence that this can confuse Purify.
    101 // This adaptor can only be applied to raw allocators
    102 
    103 template <class _Alloc>
    104 class __debug_alloc : public _Alloc {
    105 public:
    106   typedef _Alloc __allocator_type;
    107   typedef typename _Alloc::value_type value_type;
    108 private:
    109   struct __alloc_header {
    110     size_t __magic: 16;
    111     size_t __type_size:16;
    112     _STLP_UINT32_T _M_size;
    113   }; // that is 8 bytes for sure
    114   // Sunpro CC has bug on enums, so extra_before/after set explicitly
    115   enum { __pad = 8, __magic = 0xdeba, __deleted_magic = 0xdebd,
    116          __shred_byte = _STLP_SHRED_BYTE };
    117 
    118   enum { __extra_before = 16, __extra_after = 8 };
    119   // Size of space used to store size.  Note
    120   // that this must be large enough to preserve
    121   // alignment.
    122   static size_t _STLP_CALL __extra_before_chunk() {
    123     return (long)__extra_before / sizeof(value_type) +
    124       (size_t)((long)__extra_before % sizeof(value_type) > 0);
    125   }
    126   static size_t _STLP_CALL __extra_after_chunk() {
    127     return (long)__extra_after / sizeof(value_type) +
    128       (size_t)((long)__extra_after % sizeof(value_type) > 0);
    129   }
    130 public:
    131   __debug_alloc() {}
    132   ~__debug_alloc() {}
    133   static void* _STLP_CALL allocate(size_t);
    134   static void _STLP_CALL deallocate(void *, size_t);
    135 };
    136 
    137 #  if defined (__OS400__)
    138 // dums 02/05/2007: is it really necessary ?
    139 enum { _MAX_BYTES = 256 };
    140 #  else
    141 enum { _MAX_BYTES = 32 * sizeof(void*) };
    142 #  endif
    143 
    144 #if !defined (_STLP_USE_NO_IOSTREAMS)
    145 // Default node allocator.
    146 // With a reasonable compiler, this should be roughly as fast as the
    147 // original STL class-specific allocators, but with less fragmentation.
    148 class _STLP_CLASS_DECLSPEC __node_alloc {
    149   static void * _STLP_CALL _M_allocate(size_t& __n);
    150   /* __p may not be 0 */
    151   static void _STLP_CALL _M_deallocate(void *__p, size_t __n);
    152 
    153 public:
    154   // this one is needed for proper simple_alloc wrapping
    155   typedef char value_type;
    156   /* __n must be > 0      */
    157   static void* _STLP_CALL allocate(size_t& __n)
    158   { return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); }
    159   /* __p may not be 0 */
    160   static void _STLP_CALL deallocate(void *__p, size_t __n)
    161   { if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); }
    162 };
    163 
    164 #  if defined (_STLP_USE_TEMPLATE_EXPORT)
    165 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__node_alloc>;
    166 #  endif
    167 
    168 #endif
    169 
    170 #if defined (_STLP_USE_TEMPLATE_EXPORT)
    171 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__new_alloc>;
    172 _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__malloc_alloc>;
    173 #endif
    174 
    175 /* macro to convert the allocator for initialization
    176  * not using MEMBER_TEMPLATE_CLASSES as it should work given template constructor  */
    177 #if defined (_STLP_MEMBER_TEMPLATES) || ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    178 /* if _STLP_NO_TEMPLATE_CONVERSIONS is set, the member template constructor is
    179  * not used implicitly to convert allocator parameter, so let us do it explicitly */
    180 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_NO_TEMPLATE_CONVERSIONS)
    181 #    define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
    182 #  else
    183 #    define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __a
    184 #  endif
    185 /* else convert, but only if partial specialization works, since else
    186  * Container::allocator_type won't be different */
    187 #else
    188 #  define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
    189 #endif
    190 
    191 // Another allocator adaptor: _Alloc_traits.  This serves two
    192 // purposes.  First, make it possible to write containers that can use
    193 // either SGI-style allocators or standard-conforming allocator.
    194 
    195 // The fully general version.
    196 template <class _Tp, class _Allocator>
    197 struct _Alloc_traits {
    198   typedef _Allocator _Orig;
    199 #if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
    200   typedef typename _Allocator::_STLP_TEMPLATE rebind<_Tp> _Rebind_type;
    201   typedef typename _Rebind_type::other  allocator_type;
    202   static allocator_type create_allocator(const _Orig& __a)
    203   { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); }
    204 #else
    205   // this is not actually true, used only to pass this type through
    206   // to dynamic overload selection in _STLP_alloc_proxy methods
    207   typedef _Allocator allocator_type;
    208 #endif
    209 };
    210 
    211 #if defined (_STLP_USE_PERTHREAD_ALLOC)
    212 
    213 _STLP_END_NAMESPACE
    214 // include additional header here
    215 #  include <stl/_pthread_alloc.h>
    216 _STLP_BEGIN_NAMESPACE
    217 
    218 typedef __pthread_alloc __alloc_type;
    219 #elif defined (_STLP_USE_NEWALLOC)
    220 typedef __new_alloc __alloc_type;
    221 #elif defined (_STLP_USE_MALLOC)
    222 typedef __malloc_alloc __alloc_type;
    223 #else
    224 typedef __node_alloc __alloc_type;
    225 #endif
    226 
    227 #if defined (_STLP_DEBUG_ALLOC)
    228 typedef __debug_alloc<__alloc_type> __sgi_alloc;
    229 #else
    230 typedef __alloc_type __sgi_alloc;
    231 #endif
    232 
    233 #if !defined (_STLP_NO_ANACHRONISMS)
    234 typedef __sgi_alloc __single_client_alloc;
    235 typedef __sgi_alloc __multithreaded_alloc;
    236 #endif
    237 
    238 // This implements allocators as specified in the C++ standard.
    239 //
    240 // Note that standard-conforming allocators use many language features
    241 // that are not yet widely implemented.  In particular, they rely on
    242 // member templates, partial specialization, partial ordering of function
    243 // templates, the typename keyword, and the use of the template keyword
    244 // to refer to a template member of a dependent type.
    245 
    246 /*
    247 template <class _Tp>
    248 struct _AllocatorAux {
    249   typedef _Tp*       pointer;
    250   typedef const _Tp* const_pointer;
    251   typedef _Tp&       reference;
    252   typedef const _Tp& const_reference;
    253 
    254   pointer address(reference __x) const {return &__x;}
    255   const_pointer address(const_reference __x) const { return &__x; }
    256 };
    257 
    258 template <class _Tp>
    259 struct _AllocatorAux<const _Tp> {
    260   typedef _Tp*       pointer;
    261   typedef const _Tp* const_pointer;
    262   typedef _Tp&       reference;
    263   typedef const _Tp& const_reference;
    264 
    265   const_pointer address(const_reference __x) const { return &__x; }
    266 };
    267 */
    268 
    269 template <class _Tp>
    270 class allocator //: public _AllocatorAux<_Tp>
    271 /* A small helper struct to recognize STLport allocator implementation
    272  * from any user specialization one.
    273  */
    274                 : public __stlport_class<allocator<_Tp> >
    275 {
    276 public:
    277   typedef _Tp        value_type;
    278   typedef _Tp*       pointer;
    279   typedef const _Tp* const_pointer;
    280   typedef _Tp&       reference;
    281   typedef const _Tp& const_reference;
    282   typedef size_t     size_type;
    283   typedef ptrdiff_t  difference_type;
    284 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
    285   template <class _Tp1> struct rebind {
    286     typedef allocator<_Tp1> other;
    287   };
    288 #endif
    289   allocator() _STLP_NOTHROW {}
    290 #if defined (_STLP_MEMBER_TEMPLATES)
    291   template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
    292 #endif
    293   allocator(const allocator<_Tp>&) _STLP_NOTHROW {}
    294 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    295   allocator(__move_source<allocator<_Tp> > src) _STLP_NOTHROW {}
    296 #endif
    297   ~allocator() _STLP_NOTHROW {}
    298   pointer address(reference __x) const {return &__x;}
    299   const_pointer address(const_reference __x) const { return &__x; }
    300   // __n is permitted to be 0.  The C++ standard says nothing about what the return value is when __n == 0.
    301   _Tp* allocate(size_type __n, const void* = 0) {
    302     if (__n > max_size()) {
    303       _STLP_THROW_BAD_ALLOC;
    304     }
    305     if (__n != 0) {
    306       size_type __buf_size = __n * sizeof(value_type);
    307       _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
    308 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
    309       memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
    310 #endif
    311       return __ret;
    312     }
    313 
    314     return 0;
    315   }
    316   // __p is permitted to be a null pointer, only if n==0.
    317   void deallocate(pointer __p, size_type __n) {
    318     _STLP_ASSERT( (__p == 0) == (__n == 0) )
    319     if (__p != 0) {
    320 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
    321       memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
    322 #endif
    323       __sgi_alloc::deallocate((void*)__p, __n * sizeof(value_type));
    324     }
    325   }
    326 #if !defined (_STLP_NO_ANACHRONISMS)
    327   // backwards compatibility
    328   void deallocate(pointer __p) const {  if (__p != 0) __sgi_alloc::deallocate((void*)__p, sizeof(value_type)); }
    329 #endif
    330   size_type max_size() const _STLP_NOTHROW  { return size_t(-1) / sizeof(value_type); }
    331   void construct(pointer __p, const_reference __val) { _STLP_STD::_Copy_Construct(__p, __val); }
    332   void destroy(pointer __p) { _STLP_STD::_Destroy(__p); }
    333 
    334 #if defined (_STLP_NO_EXTENSIONS)
    335   /* STLport extension giving rounded size of an allocated memory buffer
    336    * This method do not have to be part of a user defined allocator implementation
    337    * and won't even be called if such a function was granted.
    338    */
    339 protected:
    340 #endif
    341   _Tp* _M_allocate(size_type __n, size_type& __allocated_n) {
    342     if (__n > max_size()) {
    343       _STLP_THROW_BAD_ALLOC;
    344     }
    345 
    346     if (__n != 0) {
    347       size_type __buf_size = __n * sizeof(value_type);
    348       _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
    349 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
    350       memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
    351 #endif
    352       __allocated_n = __buf_size / sizeof(value_type);
    353       return __ret;
    354     }
    355 
    356     return 0;
    357   }
    358 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
    359   void _M_swap_workaround(allocator<_Tp>& __other) {}
    360 #endif
    361 };
    362 
    363 _STLP_TEMPLATE_NULL
    364 class _STLP_CLASS_DECLSPEC allocator<void> {
    365 public:
    366   typedef size_t      size_type;
    367   typedef ptrdiff_t   difference_type;
    368   typedef void*       pointer;
    369   typedef const void* const_pointer;
    370 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    371   typedef void        value_type;
    372 #endif
    373 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
    374   template <class _Tp1> struct rebind {
    375     typedef allocator<_Tp1> other;
    376   };
    377 #endif
    378 };
    379 
    380 template <class _T1, class _T2>
    381 inline bool _STLP_CALL operator==(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW
    382 { return true; }
    383 template <class _T1, class _T2>
    384 inline bool _STLP_CALL operator!=(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW
    385 { return false; }
    386 
    387 #if defined (_STLP_USE_TEMPLATE_EXPORT)
    388 _STLP_EXPORT_TEMPLATE_CLASS allocator<char>;
    389 #  if defined (_STLP_HAS_WCHAR_T)
    390 _STLP_EXPORT_TEMPLATE_CLASS allocator<wchar_t>;
    391 #  endif
    392 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
    393 _STLP_EXPORT_TEMPLATE_CLASS allocator<void*>;
    394 #  endif
    395 #endif
    396 
    397 _STLP_MOVE_TO_PRIV_NAMESPACE
    398 
    399 template <class _Tp>
    400 struct __alloc_type_traits {
    401 #if !defined (__BORLANDC__)
    402   typedef typename _IsSTLportClass<allocator<_Tp> >::_Ret _STLportAlloc;
    403 #else
    404   enum { _Is = _IsSTLportClass<allocator<_Tp> >::_Is };
    405   typedef typename __bool2type<_Is>::_Ret _STLportAlloc;
    406 #endif
    407   //The default allocator implementation which is recognize thanks to the
    408   //__stlport_class inheritance is a stateless object so:
    409   typedef _STLportAlloc has_trivial_default_constructor;
    410   typedef _STLportAlloc has_trivial_copy_constructor;
    411   typedef _STLportAlloc has_trivial_assignment_operator;
    412   typedef _STLportAlloc has_trivial_destructor;
    413   typedef _STLportAlloc is_POD_type;
    414 };
    415 
    416 _STLP_MOVE_TO_STD_NAMESPACE
    417 
    418 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    419 template <class _Tp>
    420 struct __type_traits<allocator<_Tp> > : _STLP_PRIV __alloc_type_traits<_Tp> {};
    421 #else
    422 _STLP_TEMPLATE_NULL
    423 struct __type_traits<allocator<char> > : _STLP_PRIV __alloc_type_traits<char> {};
    424 #  if defined (_STLP_HAS_WCHAR_T)
    425 _STLP_TEMPLATE_NULL
    426 struct __type_traits<allocator<wchar_t> > : _STLP_PRIV __alloc_type_traits<wchar_t> {};
    427 #  endif
    428 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
    429 _STLP_TEMPLATE_NULL
    430 struct __type_traits<allocator<void*> > : _STLP_PRIV __alloc_type_traits<void*> {};
    431 #  endif
    432 #endif
    433 
    434 
    435 #if !defined (_STLP_FORCE_ALLOCATORS)
    436 #  define _STLP_FORCE_ALLOCATORS(a,y)
    437 #endif
    438 
    439 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_MEMBER_TEMPLATE_CLASSES)
    440 // The version for the default allocator, for rare occasion when we have partial spec w/o member template classes
    441 template <class _Tp, class _Tp1>
    442 struct _Alloc_traits<_Tp, allocator<_Tp1> > {
    443   typedef allocator<_Tp1> _Orig;
    444   typedef allocator<_Tp> allocator_type;
    445   static allocator_type create_allocator(const allocator<_Tp1 >& __a)
    446   { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); }
    447 };
    448 #endif
    449 
    450 #if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) && defined (_STLP_MEMBER_TEMPLATES)
    451 template <class _Tp, class _Alloc>
    452 inline _STLP_TYPENAME_ON_RETURN_TYPE _Alloc_traits<_Tp, _Alloc>::allocator_type  _STLP_CALL
    453 __stl_alloc_create(const _Alloc& __a, const _Tp*) {
    454   typedef typename _Alloc::_STLP_TEMPLATE rebind<_Tp>::other _Rebound_type;
    455   return _Rebound_type(__a);
    456 }
    457 #else
    458 // If custom allocators are being used without member template classes support :
    459 // user (on purpose) is forced to define rebind/get operations !!!
    460 template <class _Tp1, class _Tp2>
    461 inline allocator<_Tp2>& _STLP_CALL
    462 __stl_alloc_rebind(allocator<_Tp1>& __a, const _Tp2*) {  return (allocator<_Tp2>&)(__a); }
    463 template <class _Tp1, class _Tp2>
    464 inline allocator<_Tp2> _STLP_CALL
    465 __stl_alloc_create(const allocator<_Tp1>&, const _Tp2*) { return allocator<_Tp2>(); }
    466 #endif
    467 
    468 _STLP_MOVE_TO_PRIV_NAMESPACE
    469 
    470 // inheritance is being used for EBO optimization
    471 template <class _Value, class _Tp, class _MaybeReboundAlloc>
    472 class _STLP_alloc_proxy : public _MaybeReboundAlloc {
    473 private:
    474   typedef _MaybeReboundAlloc _Base;
    475   typedef typename _Base::size_type size_type;
    476   typedef _STLP_alloc_proxy<_Value, _Tp, _MaybeReboundAlloc> _Self;
    477 public:
    478   _Value _M_data;
    479 
    480   _STLP_alloc_proxy (const _MaybeReboundAlloc& __a, _Value __p) :
    481     _MaybeReboundAlloc(__a), _M_data(__p) {}
    482 
    483 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    484   _STLP_alloc_proxy (__move_source<_Self> src) :
    485     _Base(_STLP_PRIV _AsMoveSource(src.get()._M_base())),
    486     _M_data(_STLP_PRIV _AsMoveSource(src.get()._M_data)) {}
    487 
    488   _Base& _M_base()
    489   { return *this; }
    490 #endif
    491 
    492 private:
    493   /* Following are helper methods to detect stateless allocators and avoid
    494    * swap in this case. For some compilers (VC6) it is a workaround for a
    495    * compiler bug in the Empty Base class Optimization feature, for others
    496    * it is a small optimization or nothing if no EBO. */
    497   void _M_swap_alloc(_Self&, const __true_type& /*_IsStateless*/)
    498   {}
    499 
    500   void _M_swap_alloc(_Self& __x, const __false_type& /*_IsStateless*/) {
    501     _MaybeReboundAlloc &__base_this = *this;
    502     _MaybeReboundAlloc &__base_x = __x;
    503     _STLP_STD::swap(__base_this, __base_x);
    504   }
    505 
    506 public:
    507   void _M_swap_alloc(_Self& __x) {
    508 #if !defined (__BORLANDC__)
    509     typedef typename _IsStateless<_MaybeReboundAlloc>::_Ret _StatelessAlloc;
    510 #else
    511     typedef typename __bool2type<_IsStateless<_MaybeReboundAlloc>::_Is>::_Ret _StatelessAlloc;
    512 #endif
    513     _M_swap_alloc(__x, _StatelessAlloc());
    514   }
    515 
    516   /* We need to define the following swap implementation for allocator with state
    517    * as those allocators might have implement a special swap function to correctly
    518    * move datas from an instance to the oher, _STLP_alloc_proxy should not break
    519    * this mecanism. */
    520   void swap(_Self& __x) {
    521     _M_swap_alloc(__x);
    522     _STLP_STD::swap(_M_data, __x._M_data);
    523   }
    524 
    525   _Tp* allocate(size_type __n, size_type& __allocated_n) {
    526 #if !defined (__BORLANDC__)
    527     typedef typename _IsSTLportClass<_MaybeReboundAlloc>::_Ret _STLportAlloc;
    528 #else
    529     typedef typename __bool2type<_IsSTLportClass<_MaybeReboundAlloc>::_Is>::_Ret _STLportAlloc;
    530 #endif
    531     return allocate(__n, __allocated_n, _STLportAlloc());
    532   }
    533 
    534   // Unified interface to perform allocate()/deallocate() with limited
    535   // language support
    536 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
    537   // else it is rebound already, and allocate() member is accessible
    538   _Tp* allocate(size_type __n)
    539   { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, 0); }
    540   void deallocate(_Tp* __p, size_type __n)
    541   { __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).deallocate(__p, __n); }
    542 private:
    543   _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
    544   { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0))._M_allocate(__n, __allocated_n); }
    545 #else
    546   //Expose Standard allocate overload (using expression do not work for some compilers (Borland))
    547   _Tp* allocate(size_type __n)
    548   { return _Base::allocate(__n); }
    549 private:
    550   _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
    551   { return _Base::_M_allocate(__n, __allocated_n); }
    552 #endif
    553 
    554   _Tp* allocate(size_type __n, size_type& __allocated_n, const __false_type& /*STLport allocator*/)
    555   { __allocated_n = __n; return allocate(__n); }
    556 };
    557 
    558 #if defined (_STLP_USE_TEMPLATE_EXPORT)
    559 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<char*, char, allocator<char> >;
    560 #  if defined (_STLP_HAS_WCHAR_T)
    561 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<wchar_t*, wchar_t, allocator<wchar_t> >;
    562 #  endif
    563 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
    564 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<void**, void*, allocator<void*> >;
    565 #  endif
    566 #endif
    567 
    568 _STLP_MOVE_TO_STD_NAMESPACE
    569 _STLP_END_NAMESPACE
    570 
    571 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
    572 #  include <stl/_alloc.c>
    573 #endif
    574 
    575 #endif /* _STLP_INTERNAL_ALLOC_H */
    576 
    577 // Local Variables:
    578 // mode:C++
    579 // End:
    580 
    581