PageRenderTime 49ms CodeModel.GetById 13ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/stlport/stlport/stl/_alloc.h

https://github.com/aichunyu/FFPlayer
C Header | 675 lines | 463 code | 85 blank | 127 comment | 60 complexity | fccee764962926905bdf0560f64d5058 MD5 | raw file
  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)
 76template <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)
 83typedef void (* __oom_handler_type)();
 84#endif
 85
 86class _STLP_CLASS_DECLSPEC __malloc_alloc {
 87public:
 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.
121class _STLP_CLASS_DECLSPEC __new_alloc {
122public:
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
142template <class _Alloc>
143class __debug_alloc : public _Alloc {
144public:
145  typedef _Alloc __allocator_type;
146  typedef typename _Alloc::value_type value_type;
147private:
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  }
169public:
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)
182enum {_ALIGN = 16, _ALIGN_SHIFT = 4, _MAX_BYTES = 256};
183#  else
184enum {_ALIGN = 8, _ALIGN_SHIFT = 3, _MAX_BYTES = 128};
185#  endif /* __OS400__ */
186
187#if !defined (_STLP_USE_NO_IOSTREAMS)
188
189#  if !defined (_STLP_USE_SIMPLE_NODE_ALLOC)
190// Default node allocator.
191// With a reasonable compiler, this should be roughly as fast as the
192// original STL class-specific allocators, but with less fragmentation.
193// Define _STLP_USE_SIMPLE_NODE_ALLOC to use __new_alloc instead, which
194// can be implemented without out-of-line functions.
195class _STLP_CLASS_DECLSPEC __node_alloc {
196  static void * _STLP_CALL _M_allocate(size_t& __n);
197  /* __p may not be 0 */
198  static void _STLP_CALL _M_deallocate(void *__p, size_t __n);
199
200public:
201  // this one is needed for proper simple_alloc wrapping
202  typedef char value_type;
203#  if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS)
204  template <class _Tp1> struct rebind {
205    typedef __allocator<_Tp1, __node_alloc> other;
206  };
207#  endif
208  /* __n must be > 0      */
209  static void* _STLP_CALL allocate(size_t& __n)
210  { return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); }
211  /* __p may not be 0 */
212  static void _STLP_CALL deallocate(void *__p, size_t __n)
213  { if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); }
214};
215
216#    if defined (_STLP_USE_TEMPLATE_EXPORT)
217_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__node_alloc>;
218#    endif
219
220#  else /* _STLP_USE_SIMPLE_NODE_ALLOC */
221// Use __new_alloc instead of __node_alloc. This prevents the need for
222// out-of-line _M_allocate and _M_dealloacte functions.
223typedef __new_alloc __node_alloc;
224
225#  endif /* _STLP_USE_SIMPLE_NODE_ALLOC */
226
227#endif /* _STLP_USE_NO_IOSTREAMS */
228
229#if defined (_STLP_USE_TEMPLATE_EXPORT)
230_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__new_alloc>;
231_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__malloc_alloc>;
232#endif
233
234/* macro to convert the allocator for initialization
235 * not using MEMBER_TEMPLATE_CLASSES as it should work given template constructor  */
236#if defined (_STLP_MEMBER_TEMPLATES) || ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
237/* if _STLP_NO_TEMPLATE_CONVERSIONS is set, the member template constructor is
238 * not used implicitly to convert allocator parameter, so let us do it explicitly */
239#  if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_NO_TEMPLATE_CONVERSIONS)
240#    define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
241#  else
242#    define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __a
243#  endif
244/* else convert, but only if partial specialization works, since else
245 * Container::allocator_type won't be different */
246#else
247#  define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)
248#endif /* _STLP_MEMBER_TEMPLATES || !_STLP_CLASS_PARTIAL_SPECIALIZATION */
249
250// Another allocator adaptor: _Alloc_traits.  This serves two
251// purposes.  First, make it possible to write containers that can use
252// either SGI-style allocators or standard-conforming allocator.
253
254// The fully general version.
255template <class _Tp, class _Allocator>
256struct _Alloc_traits {
257  typedef _Allocator _Orig;
258#if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
259  typedef typename _Allocator::_STLP_TEMPLATE rebind<_Tp> _Rebind_type;
260  typedef typename _Rebind_type::other  allocator_type;
261  static allocator_type create_allocator(const _Orig& __a)
262  { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); }
263#else
264  // this is not actually true, used only to pass this type through
265  // to dynamic overload selection in _STLP_alloc_proxy methods
266  typedef _Allocator allocator_type;
267#endif /* !_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
268};
269
270#if defined (_STLP_USE_PERTHREAD_ALLOC)
271
272_STLP_END_NAMESPACE
273
274// include additional header here
275#  include <stl/_pthread_alloc.h>
276
277_STLP_BEGIN_NAMESPACE
278
279#  if defined (_STLP_DEBUG_ALLOC)
280typedef __debug_alloc<__pthread_alloc> __sgi_alloc;
281#  else
282typedef __pthread_alloc __sgi_alloc;
283#  endif /* _STLP_DEBUG_ALLOC */
284
285typedef __pthread_alloc __single_client_alloc;
286typedef __pthread_alloc __multithreaded_alloc;
287
288#else /* _STLP_USE_PERTHREAD_ALLOC */
289
290#  if defined (_STLP_USE_NEWALLOC)
291
292#    if defined (_STLP_DEBUG_ALLOC)
293typedef __debug_alloc<__new_alloc> __sgi_alloc;
294#    else
295typedef __new_alloc __sgi_alloc;
296#    endif /* _STLP_DEBUG_ALLOC */
297
298typedef __new_alloc __single_client_alloc;
299typedef __new_alloc __multithreaded_alloc;
300
301#  elif defined (_STLP_USE_MALLOC)
302
303#    if defined (_STLP_DEBUG_ALLOC)
304typedef __debug_alloc<__malloc_alloc> __sgi_alloc;
305#    else
306typedef __malloc_alloc __sgi_alloc;
307#    endif /* _STLP_DEBUG_ALLOC */
308
309typedef __malloc_alloc __single_client_alloc;
310typedef __malloc_alloc __multithreaded_alloc;
311
312#  else
313
314#    if defined (_STLP_DEBUG_ALLOC)
315typedef __debug_alloc<__node_alloc> __sgi_alloc;
316#    else
317typedef __node_alloc __sgi_alloc;
318#    endif
319
320typedef __node_alloc __single_client_alloc;
321typedef __node_alloc __multithreaded_alloc;
322
323#  endif /* _STLP_USE_NEWALLOC */
324#endif /* _STLP_USE_PERTHREAD_ALLOC */
325
326// This implements allocators as specified in the C++ standard.
327//
328// Note that standard-conforming allocators use many language features
329// that are not yet widely implemented.  In particular, they rely on
330// member templates, partial specialization, partial ordering of function
331// templates, the typename keyword, and the use of the template keyword
332// to refer to a template member of a dependent type.
333
334/*
335template <class _Tp>
336struct _AllocatorAux {
337  typedef _Tp*       pointer;
338  typedef const _Tp* const_pointer;
339  typedef _Tp&       reference;
340  typedef const _Tp& const_reference;
341
342  pointer address(reference __x) const {return &__x;}
343  const_pointer address(const_reference __x) const { return &__x; }
344};
345
346template <class _Tp>
347struct _AllocatorAux<const _Tp> {
348  typedef _Tp*       pointer;
349  typedef const _Tp* const_pointer;
350  typedef _Tp&       reference;
351  typedef const _Tp& const_reference;
352
353  const_pointer address(const_reference __x) const { return &__x; }
354};
355*/
356
357template <class _Tp>
358class allocator //: public _AllocatorAux<_Tp>
359/* A small helper struct to recognize STLport allocator implementation
360 * from any user specialization one.
361 */
362                : public __stlport_class<allocator<_Tp> > {
363public:
364  typedef _Tp        value_type;
365  typedef _Tp*       pointer;
366  typedef const _Tp* const_pointer;
367  typedef _Tp&       reference;
368  typedef const _Tp& const_reference;
369  typedef size_t     size_type;
370  typedef ptrdiff_t  difference_type;
371#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
372  template <class _Tp1> struct rebind {
373    typedef allocator<_Tp1> other;
374  };
375#endif
376  allocator() _STLP_NOTHROW {}
377#if defined (_STLP_MEMBER_TEMPLATES)
378  template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
379#endif
380  allocator(const allocator<_Tp>&) _STLP_NOTHROW {}
381  allocator(__move_source<allocator<_Tp> > src) _STLP_NOTHROW {}
382  ~allocator() _STLP_NOTHROW {}
383  pointer address(reference __x) const {return &__x;}
384  const_pointer address(const_reference __x) const { return &__x; }
385  // __n is permitted to be 0.  The C++ standard says nothing about what the return value is when __n == 0.
386  _Tp* allocate(size_type __n, const void* = 0) {
387    if (__n > max_size()) {
388      __THROW_BAD_ALLOC;
389    }
390    if (__n != 0) {
391      size_type __buf_size = __n * sizeof(value_type);
392      _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
393#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
394      if (__ret != 0) {
395        memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
396      }
397#endif
398      return __ret;
399    }
400    else
401      return 0;
402  }
403  // __p is permitted to be a null pointer, only if n==0.
404  void deallocate(pointer __p, size_type __n) {
405    _STLP_ASSERT( (__p == 0) == (__n == 0) )
406    if (__p != 0) {
407#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
408      memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
409#endif
410      __sgi_alloc::deallocate((void*)__p, __n * sizeof(value_type));
411    }
412  }
413  // backwards compatibility
414  void deallocate(pointer __p) const {  if (__p != 0) __sgi_alloc::deallocate((void*)__p, sizeof(value_type)); }
415  size_type max_size() const _STLP_NOTHROW  { return size_t(-1) / sizeof(value_type); }
416  void construct(pointer __p, const_reference __val) { _STLP_STD::_Copy_Construct(__p, __val); }
417  void destroy(pointer __p) { _STLP_STD::_Destroy(__p); }
418#if defined(__MRC__)||(defined(__SC__) && !defined(__DMC__))
419  template <class _T2> bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; }
420  template <class _T2> bool operator!=(const allocator<_T2>&) const _STLP_NOTHROW { return false; }
421#endif
422
423#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
424  //This is just to make swap workaround for compiler without template function partial
425  //happy.
426  void swap(allocator<_Tp>&) {}
427#endif
428
429#if defined (_STLP_NO_EXTENSIONS)
430  /* STLport extension giving rounded size of an allocated memory buffer
431   * This method do not have to be part of a user defined allocator implementation
432   * and won't even be called if such a function was granted.
433   */
434protected:
435#endif
436  _Tp* allocate(size_type __n, size_type& __allocated_n) {
437    if (__n > max_size()) {
438      __THROW_BAD_ALLOC;
439    }
440
441    if (__n != 0) {
442      size_type __buf_size = __n * sizeof(value_type);
443      _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
444#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
445      if (__ret != 0) {
446        memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
447      }
448#endif
449      __allocated_n = __buf_size / sizeof(value_type);
450      return __ret;
451    }
452    else
453      return 0;
454  }
455};
456
457_STLP_TEMPLATE_NULL
458class _STLP_CLASS_DECLSPEC allocator<void> {
459public:
460  typedef size_t      size_type;
461  typedef ptrdiff_t   difference_type;
462  typedef void*       pointer;
463  typedef const void* const_pointer;
464#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
465  typedef void        value_type;
466#endif
467#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
468  template <class _Tp1> struct rebind {
469    typedef allocator<_Tp1> other;
470  };
471#endif
472#if defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__))  //*ty 03/24/2001 - MPW compilers get confused on these operator definitions
473  template <class _T2> bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; }
474  template <class _T2> bool operator!=(const allocator<_T2>&) const _STLP_NOTHROW { return false; }
475#endif
476};
477
478#if !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__)))  //*ty 03/24/2001 - MPW compilers get confused on these operator definitions
479template <class _T1, class _T2> inline bool  _STLP_CALL operator==(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW { return true; }
480template <class _T1, class _T2> inline bool  _STLP_CALL operator!=(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW { return false; }
481#endif
482
483#if defined (_STLP_USE_TEMPLATE_EXPORT)
484_STLP_EXPORT_TEMPLATE_CLASS allocator<char>;
485#  if defined (_STLP_HAS_WCHAR_T)
486_STLP_EXPORT_TEMPLATE_CLASS allocator<wchar_t>;
487#  endif
488#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
489_STLP_EXPORT_TEMPLATE_CLASS allocator<void*>;
490#  endif
491#endif
492
493_STLP_MOVE_TO_PRIV_NAMESPACE
494
495template <class _Tp>
496struct __alloc_type_traits {
497#if !defined (__BORLANDC__)
498  typedef typename _IsSTLportClass<allocator<_Tp> >::_Ret _STLportAlloc;
499#else
500  enum { _Is = _IsSTLportClass<allocator<_Tp> >::_Is };
501  typedef typename __bool2type<_Is>::_Ret _STLportAlloc;
502#endif
503  //The default allocator implementation which is recognize thanks to the
504  //__stlport_class inheritance is a stateless object so:
505  typedef _STLportAlloc has_trivial_default_constructor;
506  typedef _STLportAlloc has_trivial_copy_constructor;
507  typedef _STLportAlloc has_trivial_assignment_operator;
508  typedef _STLportAlloc has_trivial_destructor;
509  typedef _STLportAlloc is_POD_type;
510};
511
512_STLP_MOVE_TO_STD_NAMESPACE
513
514#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
515template <class _Tp>
516struct __type_traits<allocator<_Tp> > : _STLP_PRIV __alloc_type_traits<_Tp> {};
517#else
518_STLP_TEMPLATE_NULL
519struct __type_traits<allocator<char> > : _STLP_PRIV __alloc_type_traits<char> {};
520#  if defined (_STLP_HAS_WCHAR_T)
521_STLP_TEMPLATE_NULL
522struct __type_traits<allocator<wchar_t> > : _STLP_PRIV __alloc_type_traits<wchar_t> {};
523#  endif
524#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
525_STLP_TEMPLATE_NULL
526struct __type_traits<allocator<void*> > : _STLP_PRIV __alloc_type_traits<void*> {};
527#  endif
528#endif
529
530
531#if !defined (_STLP_FORCE_ALLOCATORS)
532#  define _STLP_FORCE_ALLOCATORS(a,y)
533#endif
534
535#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_MEMBER_TEMPLATE_CLASSES)
536// The version for the default allocator, for rare occasion when we have partial spec w/o member template classes
537template <class _Tp, class _Tp1>
538struct _Alloc_traits<_Tp, allocator<_Tp1> > {
539  typedef allocator<_Tp1> _Orig;
540  typedef allocator<_Tp> allocator_type;
541  static allocator_type create_allocator(const allocator<_Tp1 >& __a)
542  { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); }
543};
544#endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
545
546#if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) && defined (_STLP_MEMBER_TEMPLATES)
547template <class _Tp, class _Alloc>
548inline _STLP_TYPENAME_ON_RETURN_TYPE _Alloc_traits<_Tp, _Alloc>::allocator_type  _STLP_CALL
549__stl_alloc_create(const _Alloc& __a, const _Tp*) {
550  typedef typename _Alloc::_STLP_TEMPLATE rebind<_Tp>::other _Rebound_type;
551  return _Rebound_type(__a);
552}
553#else
554// If custom allocators are being used without member template classes support :
555// user (on purpose) is forced to define rebind/get operations !!!
556template <class _Tp1, class _Tp2>
557inline allocator<_Tp2>& _STLP_CALL
558__stl_alloc_rebind(allocator<_Tp1>& __a, const _Tp2*) {  return (allocator<_Tp2>&)(__a); }
559template <class _Tp1, class _Tp2>
560inline allocator<_Tp2> _STLP_CALL
561__stl_alloc_create(const allocator<_Tp1>&, const _Tp2*) { return allocator<_Tp2>(); }
562#endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
563
564#if defined (_STLP_USE_RAW_SGI_ALLOCATORS)
565// move obsolete stuff out of the way
566#  include <stl/_alloc_old.h>
567#endif
568
569_STLP_MOVE_TO_PRIV_NAMESPACE
570
571// inheritance is being used for EBO optimization
572template <class _Value, class _Tp, class _MaybeReboundAlloc>
573class _STLP_alloc_proxy : public _MaybeReboundAlloc {
574private:
575  typedef _MaybeReboundAlloc _Base;
576  typedef typename _Base::size_type size_type;
577  typedef _STLP_alloc_proxy<_Value, _Tp, _MaybeReboundAlloc> _Self;
578public:
579  _Value _M_data;
580
581  _STLP_alloc_proxy (const _MaybeReboundAlloc& __a, _Value __p) :
582    _MaybeReboundAlloc(__a), _M_data(__p) {}
583
584  _STLP_alloc_proxy (__move_source<_Self> src) :
585    _MaybeReboundAlloc(_STLP_PRIV _AsMoveSource<_Base>(src.get())),
586    _M_data(_STLP_PRIV _AsMoveSource<_Value>(src.get()._M_data)) {}
587
588private:
589  /* Following are helper methods to detect stateless allocators and avoid
590   * swap in this case. For some compilers (VC6) it is a workaround for a
591   * compiler bug in the Empty Base class Optimization feature, for others
592   * it is a small optimization or nothing if no EBO. */
593  void _M_swap_alloc(_Self&, const __true_type& /*_IsStateless*/)
594  {}
595
596  void _M_swap_alloc(_Self& __x, const __false_type& /*_IsStateless*/) {
597    _MaybeReboundAlloc &__base_this = *this;
598    _MaybeReboundAlloc &__base_x = __x;
599    _STLP_STD::swap(__base_this, __base_x);
600  }
601
602public:
603  void _M_swap_alloc(_Self& __x) {
604#if !defined (__BORLANDC__)
605    typedef typename _IsStateless<_MaybeReboundAlloc>::_Ret _StatelessAlloc;
606#else
607    typedef typename __bool2type<_IsStateless<_MaybeReboundAlloc>::_Is>::_Ret _StatelessAlloc;
608#endif
609    _M_swap_alloc(__x, _StatelessAlloc());
610  }
611
612  /* We need to define the following swap implementation for allocator with state
613   * as those allocators might have implement a special swap function to correctly
614   * move datas from an instance to the oher, _STLP_alloc_proxy should not break
615   * this mecanism. */
616  void swap(_Self& __x) {
617    _M_swap_alloc(__x);
618    _STLP_STD::swap(_M_data, __x._M_data);
619  }
620
621  _Tp* allocate(size_type __n, size_type& __allocated_n) {
622#if !defined (__BORLANDC__)
623    typedef typename _IsSTLportClass<_MaybeReboundAlloc>::_Ret _STLportAlloc;
624#else
625    typedef typename __bool2type<_IsSTLportClass<_MaybeReboundAlloc>::_Is>::_Ret _STLportAlloc;
626#endif
627    return allocate(__n, __allocated_n, _STLportAlloc());
628  }
629
630  // Unified interface to perform allocate()/deallocate() with limited
631  // language support
632#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
633  // else it is rebound already, and allocate() member is accessible
634  _Tp* allocate(size_type __n)
635  { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, 0); }
636  void deallocate(_Tp* __p, size_type __n)
637  { __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).deallocate(__p, __n); }
638private:
639  _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
640  { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, __allocated_n); }
641#else
642  //Expose Standard allocate overload (using expression do not work for some compilers (Borland))
643  _Tp* allocate(size_type __n)
644  { return _Base::allocate(__n); }
645private:
646  _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/)
647  { return _Base::allocate(__n, __allocated_n); }
648#endif
649
650  _Tp* allocate(size_type __n, size_type& __allocated_n, const __false_type& /*STLport allocator*/)
651  { __allocated_n = __n; return allocate(__n); }
652};
653
654#if defined (_STLP_USE_TEMPLATE_EXPORT)
655_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<char*, char, allocator<char> >;
656#  if defined (_STLP_HAS_WCHAR_T)
657_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<wchar_t*, wchar_t, allocator<wchar_t> >;
658#  endif
659#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
660_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<void**, void*, allocator<void*> >;
661#  endif
662#endif
663
664_STLP_MOVE_TO_STD_NAMESPACE
665_STLP_END_NAMESPACE
666
667#if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
668#  include <stl/_alloc.c>
669#endif
670
671#endif /* _STLP_INTERNAL_ALLOC_H */
672
673// Local Variables:
674// mode:C++
675// End: