]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/stl/stl/_alloc.h
Add STLport 5.1.4
[polintos/scott/priv.git] / include / c++ / stl / stl / _alloc.h
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 private:
578   /* Following are helper methods to detect stateless allocators and avoid
579    * swap in this case. For some compilers (VC6) it is a workaround for a
580    * compiler bug in the Empty Base class Optimization feature, for others
581    * it is a small optimization or nothing if no EBO. */
582   void _M_swap_alloc(_Self&, const __true_type& /*_IsStateless*/)
583   {}
584
585   void _M_swap_alloc(_Self& __x, const __false_type& /*_IsStateless*/) {
586     _MaybeReboundAlloc &__base_this = *this;
587     _MaybeReboundAlloc &__base_x = __x;
588     _STLP_STD::swap(__base_this, __base_x);
589   }
590
591 public:
592   void _M_swap_alloc(_Self& __x) {
593 #if !defined (__BORLANDC__)
594     typedef typename _IsStateless<_MaybeReboundAlloc>::_Ret _StatelessAlloc;
595 #else
596     typedef typename __bool2type<_IsStateless<_MaybeReboundAlloc>::_Is>::_Ret _StatelessAlloc;
597 #endif
598     _M_swap_alloc(__x, _StatelessAlloc());
599   }
600
601   /* We need to define the following swap implementation for allocator with state
602    * as those allocators might have implement a special swap function to correctly
603    * move datas from an instance to the oher, _STLP_alloc_proxy should not break
604    * this mecanism. */
605   void swap(_Self& __x) {
606     _M_swap_alloc(__x);
607     _STLP_STD::swap(_M_data, __x._M_data);
608   }
609
610   _Tp* allocate(size_type __n, size_type& __allocated_n) {
611 #if !defined (__BORLANDC__)
612     typedef typename _IsSTLportClass<_MaybeReboundAlloc>::_Ret _STLportAlloc;
613 #else
614     typedef typename __bool2type<_IsSTLportClass<_MaybeReboundAlloc>::_Is>::_Ret _STLportAlloc;
615 #endif
616     return allocate(__n, __allocated_n, _STLportAlloc());
617   }
618
619   // Unified interface to perform allocate()/deallocate() with limited
620   // language support
621 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
622   // else it is rebound already, and allocate() member is accessible
623   _Tp* allocate(size_type __n)
624   { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, 0); }
625   void deallocate(_Tp* __p, size_type __n)
626   { __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).deallocate(__p, __n); }
627 private:
628   _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
629   { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, __allocated_n); }
630 #else
631   //Expose Standard allocate overload (using expression do not work for some compilers (Borland))
632   _Tp* allocate(size_type __n)
633   { return _Base::allocate(__n); }
634 private:
635   _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
636   { return _Base::allocate(__n, __allocated_n); }
637 #endif
638
639   _Tp* allocate(size_type __n, size_type& __allocated_n, const __false_type& /*STLport allocator*/)
640   { __allocated_n = __n; return allocate(__n); }
641 };
642
643 #if defined (_STLP_USE_TEMPLATE_EXPORT)
644 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<char*, char, allocator<char> >;
645 #  if defined (_STLP_HAS_WCHAR_T)
646 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<wchar_t*, wchar_t, allocator<wchar_t> >;
647 #  endif
648 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
649 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<void**, void*, allocator<void*> >;
650 #  endif
651 #endif
652
653 _STLP_MOVE_TO_STD_NAMESPACE
654 _STLP_END_NAMESPACE
655
656 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
657 #  include <stl/_alloc.c>
658 #endif
659
660 #endif /* _STLP_INTERNAL_ALLOC_H */
661
662 // Local Variables:
663 // mode:C++
664 // End:
665