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