111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1994
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Hewlett-Packard Company
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1996,1997
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Silicon Graphics Computer Systems, Inc.
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1997
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Moscow Center for SPARC Technology
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1999
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Boris Fomitchev
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This material is provided "as is", with absolutely no warranty expressed
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * or implied. Any use is at your own risk.
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to use or copy this software for any purpose is hereby granted
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * without fee, provided the above notices are retained on all copies.
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to modify the code and to distribute modified code is granted,
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * provided the above notices are retained, and a notice that the code was
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * modified is included with the above copyright notice.
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_PTHREAD_ALLOC_H
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _STLP_PTHREAD_ALLOC_H
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Pthread-specific node allocator.
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This is similar to the default allocator, except that free-list
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * information is kept separately for each thread, avoiding locking.
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This should be reasonably fast even in the presence of threads.
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The down side is that storage may not be well-utilized.
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * It is not an error to allocate memory in thread A and deallocate
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * it in thread B.  But this effectively transfers ownership of the memory,
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * so that it can only be reallocated by thread B.  Thus this can effectively
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * result in a storage leak if it's done on a regular basis.
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * It can also result in frequent sharing of
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * cache lines among processors, with potentially serious performance
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * consequences.
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_PTHREADS)
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  error POSIX specific allocator implementation. Your system do not seems to \
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberthave this interface so please comment the _STLP_USE_PERTHREAD_ALLOC macro \
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertor report to the STLport forum.
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_USE_NO_IOSTREAMS)
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  error You cannot use per thread allocator implementation without building \
5211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertSTLport libraries.
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_ALLOC_H
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  include <stl/_alloc.h>
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_BEGIN_NAMESPACE
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_MOVE_TO_PRIV_NAMESPACE
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _Pthread_alloc_per_thread_state;
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Pthread-specific allocator.
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _STLP_CLASS_DECLSPEC _Pthread_alloc {
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: // but only for internal use:
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Pthread_alloc_per_thread_state __state_type;
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef char value_type;
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Return a recycled or new per thread state.
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static __state_type * _STLP_CALL _S_get_per_thread_state();
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* n must be > 0      */
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void * _STLP_CALL allocate(size_t& __n);
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* p may not be 0 */
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void _STLP_CALL deallocate(void *__p, size_t __n);
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // boris : versions for per_thread_allocator
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* n must be > 0      */
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void * _STLP_CALL allocate(size_t& __n, __state_type* __a);
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* p may not be 0 */
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void _STLP_CALL deallocate(void *__p, size_t __n, __state_type* __a);
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void * _STLP_CALL reallocate(void *__p, size_t __old_sz, size_t& __new_sz);
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_MOVE_TO_STD_NAMESPACE
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef _STLP_PRIV _Pthread_alloc __pthread_alloc;
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef __pthread_alloc pthread_alloc;
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp>
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass pthread_allocator : public __stlport_class<pthread_allocator<_Tp> > {
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef pthread_alloc _S_Alloc;          // The underlying allocator.
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef size_t     size_type;
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ptrdiff_t  difference_type;
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Tp*       pointer;
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const _Tp* const_pointer;
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Tp&       reference;
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const _Tp& const_reference;
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Tp        value_type;
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template <class _NewType> struct rebind {
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef pthread_allocator<_NewType> other;
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pthread_allocator() _STLP_NOTHROW {}
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pthread_allocator(const pthread_allocator<_Tp>& a) _STLP_NOTHROW {}
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template <class _OtherType> pthread_allocator(const pthread_allocator<_OtherType>&)
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_NOTHROW {}
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~pthread_allocator() _STLP_NOTHROW {}
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pointer address(reference __x) const { return &__x; }
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const_pointer address(const_reference __x) const { return &__x; }
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // __n is permitted to be 0.  The C++ standard says nothing about what
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // the return value is when __n == 0.
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Tp* allocate(size_type __n, const void* = 0) {
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n > max_size()) {
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_THROW_BAD_ALLOC;
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n != 0) {
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_type __buf_size = __n * sizeof(value_type);
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return 0;
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void deallocate(pointer __p, size_type __n) {
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT( (__p == 0) == (__n == 0) )
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__p != 0) {
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_Alloc::deallocate(__p, __n * sizeof(value_type));
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_type max_size() const _STLP_NOTHROW
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { return size_t(-1) / sizeof(_Tp); }
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void destroy(pointer _p) { _p->~_Tp(); }
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_NO_EXTENSIONS)
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* STLport extension giving rounded size of an allocated memory buffer
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * This method do not have to be part of a user defined allocator implementation
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * and won't even be called if such a function was granted.
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprotected:
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Tp* allocate(size_type __n, size_type& __allocated_n) {
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n > max_size()) {
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_THROW_BAD_ALLOC;
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n != 0) {
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_type __buf_size = __n * sizeof(value_type);
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __allocated_n = __buf_size / sizeof(value_type);
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return 0;
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void _M_swap_workaround(pthread_allocator<_Tp>& __x) {}
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _STLP_CLASS_DECLSPEC pthread_allocator<void> {
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef size_t      size_type;
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ptrdiff_t   difference_type;
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef void*       pointer;
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const void* const_pointer;
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef void        value_type;
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template <class _NewType> struct rebind {
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef pthread_allocator<_NewType> other;
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _T1, class _T2>
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline bool operator==(const pthread_allocator<_T1>&,
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                       const pthread_allocator<_T2>& a2)
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return true; }
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _T1, class _T2>
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline bool operator!=(const pthread_allocator<_T1>&,
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                       const pthread_allocator<_T2>&)
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return false; }
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp, class _Atype>
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ typedef pthread_allocator<_Tp> allocator_type; };
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp1, class _Tp2>
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline pthread_allocator<_Tp2>&
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__stl_alloc_rebind(pthread_allocator<_Tp1>& __x, const _Tp2*)
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return (pthread_allocator<_Tp2>&)__x; }
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp1, class _Tp2>
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline pthread_allocator<_Tp2>
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__stl_alloc_create(pthread_allocator<_Tp1>&, const _Tp2*)
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return pthread_allocator<_Tp2>(); }
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_MOVE_TO_PRIV_NAMESPACE
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp>
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __pthread_alloc_type_traits {
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef typename _IsSTLportClass<pthread_allocator<_Tp> >::_Ret _STLportAlloc;
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //The default allocator implementation which is recognize thanks to the
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //__stlport_class inheritance is a stateless object so:
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_default_constructor;
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_copy_constructor;
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_assignment_operator;
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_destructor;
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc is_POD_type;
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_MOVE_TO_STD_NAMESPACE
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp>
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<pthread_allocator<_Tp> > : _STLP_PRIV __pthread_alloc_type_traits<_Tp> {};
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<pthread_allocator<char> > : _STLP_PRIV __pthread_alloc_type_traits<char> {};
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_HAS_WCHAR_T)
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<pthread_allocator<wchar_t> > : _STLP_PRIV __pthread_alloc_type_traits<wchar_t> {};
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<pthread_allocator<void*> > : _STLP_PRIV __pthread_alloc_type_traits<void*> {};
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// per_thread_allocator<> : this allocator always return memory to the same thread
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// it was allocated from.
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp>
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass per_thread_allocator {
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef pthread_alloc _S_Alloc;          // The underlying allocator.
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef pthread_alloc::__state_type __state_type;
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef size_t     size_type;
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ptrdiff_t  difference_type;
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Tp*       pointer;
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const _Tp* const_pointer;
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Tp&       reference;
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const _Tp& const_reference;
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _Tp        value_type;
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template <class _NewType> struct rebind {
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef per_thread_allocator<_NewType> other;
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  per_thread_allocator() _STLP_NOTHROW {
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _M_state = _S_Alloc::_S_get_per_thread_state();
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  per_thread_allocator(const per_thread_allocator<_Tp>& __a) _STLP_NOTHROW : _M_state(__a._M_state){}
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template <class _OtherType> per_thread_allocator(const per_thread_allocator<_OtherType>& __a)
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_NOTHROW : _M_state(__a._M_state) {}
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~per_thread_allocator() _STLP_NOTHROW {}
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pointer address(reference __x) const { return &__x; }
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const_pointer address(const_reference __x) const { return &__x; }
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // __n is permitted to be 0.  The C++ standard says nothing about what
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // the return value is when __n == 0.
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Tp* allocate(size_type __n, const void* = 0) {
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n > max_size()) {
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_THROW_BAD_ALLOC;
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n != 0) {
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_type __buf_size = __n * sizeof(value_type);
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Tp* __ret = __REINTERPRET_CAST(_Tp*, _S_Alloc::allocate(__buf_size, _M_state));
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return 0;
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void deallocate(pointer __p, size_type __n) {
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_ASSERT( (__p == 0) == (__n == 0) )
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__p != 0) {
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _S_Alloc::deallocate(__p, __n * sizeof(value_type), _M_state);
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_type max_size() const _STLP_NOTHROW
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { return size_t(-1) / sizeof(_Tp); }
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void destroy(pointer _p) { _p->~_Tp(); }
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // state is being kept here
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __state_type* _M_state;
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_NO_EXTENSIONS)
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* STLport extension giving rounded size of an allocated memory buffer
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * This method do not have to be part of a user defined allocator implementation
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * and won't even be called if such a function was granted.
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprotected:
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Tp* allocate(size_type __n, size_type& __allocated_n) {
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n > max_size()) {
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_THROW_BAD_ALLOC;
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (__n != 0) {
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_type __buf_size = __n * sizeof(value_type);
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size, _M_state));
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __allocated_n = __buf_size / sizeof(value_type);
36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else
36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return 0;
36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _STLP_CLASS_DECLSPEC per_thread_allocator<void> {
37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef size_t      size_type;
37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ptrdiff_t   difference_type;
37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef void*       pointer;
37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const void* const_pointer;
37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef void        value_type;
38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template <class _NewType> struct rebind {
38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef per_thread_allocator<_NewType> other;
38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
38711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _T1, class _T2>
38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline bool operator==(const per_thread_allocator<_T1>& __a1,
38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                       const per_thread_allocator<_T2>& __a2)
39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return __a1._M_state == __a2._M_state; }
39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
39311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _T1, class _T2>
39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline bool operator!=(const per_thread_allocator<_T1>& __a1,
39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                       const per_thread_allocator<_T2>& __a2)
39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return __a1._M_state != __a2._M_state; }
39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp, class _Atype>
40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _Alloc_traits<_Tp, per_thread_allocator<_Atype> >
40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ typedef per_thread_allocator<_Tp> allocator_type; };
40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp1, class _Tp2>
41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline per_thread_allocator<_Tp2>&
41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__stl_alloc_rebind(per_thread_allocator<_Tp1>& __x, const _Tp2*)
41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return (per_thread_allocator<_Tp2>&)__x; }
41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp1, class _Tp2>
41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline per_thread_allocator<_Tp2>
41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__stl_alloc_create(per_thread_allocator<_Tp1>&, const _Tp2*)
41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ return per_thread_allocator<_Tp2>(); }
41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_MOVE_TO_PRIV_NAMESPACE
42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp>
42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __perthread_alloc_type_traits {
42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef typename _IsSTLportClass<per_thread_allocator<_Tp> >::_Ret _STLportAlloc;
42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //The default allocator implementation which is recognize thanks to the
42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //__stlport_class inheritance is a stateless object so:
42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef __false_type has_trivial_default_constructor;
43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_copy_constructor;
43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_assignment_operator;
43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef _STLportAlloc has_trivial_destructor;
43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef __false_type is_POD_type;
43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_MOVE_TO_STD_NAMESPACE
43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
43911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _Tp>
44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<per_thread_allocator<_Tp> > : _STLP_PRIV __perthread_alloc_type_traits<_Tp> {};
44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<per_thread_allocator<char> > : _STLP_PRIV __perthread_alloc_type_traits<char> {};
44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_HAS_WCHAR_T)
44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<per_thread_allocator<wchar_t> > : _STLP_PRIV __perthread_alloc_type_traits<wchar_t> {};
44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct __type_traits<per_thread_allocator<void*> > : _STLP_PRIV __perthread_alloc_type_traits<void*> {};
45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_END_NAMESPACE
45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _STLP_PTHREAD_ALLOC */
45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Local Variables:
46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// mode:C++
46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// End:
462