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