epoc32/include/tools/stlport/stl/_pthread_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.
williamr@4
     1
/*
williamr@4
     2
 *
williamr@4
     3
 * Copyright (c) 1994
williamr@4
     4
 * Hewlett-Packard Company
williamr@4
     5
 *
williamr@4
     6
 * Copyright (c) 1996,1997
williamr@4
     7
 * Silicon Graphics Computer Systems, Inc.
williamr@4
     8
 *
williamr@4
     9
 * Copyright (c) 1997
williamr@4
    10
 * Moscow Center for SPARC Technology
williamr@4
    11
 *
williamr@4
    12
 * Copyright (c) 1999
williamr@4
    13
 * Boris Fomitchev
williamr@4
    14
 *
williamr@4
    15
 * This material is provided "as is", with absolutely no warranty expressed
williamr@4
    16
 * or implied. Any use is at your own risk.
williamr@4
    17
 *
williamr@4
    18
 * Permission to use or copy this software for any purpose is hereby granted
williamr@4
    19
 * without fee, provided the above notices are retained on all copies.
williamr@4
    20
 * Permission to modify the code and to distribute modified code is granted,
williamr@4
    21
 * provided the above notices are retained, and a notice that the code was
williamr@4
    22
 * modified is included with the above copyright notice.
williamr@4
    23
 *
williamr@4
    24
 */
williamr@4
    25
williamr@4
    26
#ifndef _STLP_PTHREAD_ALLOC_H
williamr@4
    27
#define _STLP_PTHREAD_ALLOC_H
williamr@4
    28
williamr@4
    29
/*
williamr@4
    30
 * Pthread-specific node allocator.
williamr@4
    31
 * This is similar to the default allocator, except that free-list
williamr@4
    32
 * information is kept separately for each thread, avoiding locking.
williamr@4
    33
 * This should be reasonably fast even in the presence of threads.
williamr@4
    34
 * The down side is that storage may not be well-utilized.
williamr@4
    35
 * It is not an error to allocate memory in thread A and deallocate
williamr@4
    36
 * it in thread B.  But this effectively transfers ownership of the memory,
williamr@4
    37
 * so that it can only be reallocated by thread B.  Thus this can effectively
williamr@4
    38
 * result in a storage leak if it's done on a regular basis.
williamr@4
    39
 * It can also result in frequent sharing of
williamr@4
    40
 * cache lines among processors, with potentially serious performance
williamr@4
    41
 * consequences.
williamr@4
    42
 */
williamr@4
    43
williamr@4
    44
#if !defined (_STLP_PTHREADS)
williamr@4
    45
#  error POSIX specific allocator implementation. Your system do not seems to \
williamr@4
    46
have this interface so please comment the _STLP_USE_PERTHREAD_ALLOC macro \
williamr@4
    47
or report to the STLport forum.
williamr@4
    48
#endif
williamr@4
    49
williamr@4
    50
#if defined (_STLP_USE_NO_IOSTREAMS)
williamr@4
    51
#  error You cannot use per thread allocator implementation without building \
williamr@4
    52
STLport libraries.
williamr@4
    53
#endif
williamr@4
    54
williamr@4
    55
#ifndef _STLP_INTERNAL_ALLOC_H
williamr@4
    56
#  include <stl/_alloc.h>
williamr@4
    57
#endif
williamr@4
    58
williamr@4
    59
_STLP_BEGIN_NAMESPACE
williamr@4
    60
williamr@4
    61
_STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4
    62
williamr@4
    63
struct _Pthread_alloc_per_thread_state;
williamr@4
    64
williamr@4
    65
// Pthread-specific allocator.
williamr@4
    66
class _STLP_CLASS_DECLSPEC _Pthread_alloc {
williamr@4
    67
public: // but only for internal use:
williamr@4
    68
  typedef _Pthread_alloc_per_thread_state __state_type;
williamr@4
    69
  typedef char value_type;
williamr@4
    70
williamr@4
    71
public:
williamr@4
    72
  // Return a recycled or new per thread state.
williamr@4
    73
  static __state_type * _STLP_CALL _S_get_per_thread_state();
williamr@4
    74
williamr@4
    75
  /* n must be > 0      */
williamr@4
    76
  static void * _STLP_CALL allocate(size_t& __n);
williamr@4
    77
williamr@4
    78
  /* p may not be 0 */
williamr@4
    79
  static void _STLP_CALL deallocate(void *__p, size_t __n);
williamr@4
    80
williamr@4
    81
  // boris : versions for per_thread_allocator
williamr@4
    82
  /* n must be > 0      */
williamr@4
    83
  static void * _STLP_CALL allocate(size_t& __n, __state_type* __a);
williamr@4
    84
williamr@4
    85
  /* p may not be 0 */
williamr@4
    86
  static void _STLP_CALL deallocate(void *__p, size_t __n, __state_type* __a);
williamr@4
    87
williamr@4
    88
  static void * _STLP_CALL reallocate(void *__p, size_t __old_sz, size_t& __new_sz);
williamr@4
    89
};
williamr@4
    90
williamr@4
    91
_STLP_MOVE_TO_STD_NAMESPACE
williamr@4
    92
williamr@4
    93
typedef _STLP_PRIV _Pthread_alloc __pthread_alloc;
williamr@4
    94
typedef __pthread_alloc pthread_alloc;
williamr@4
    95
williamr@4
    96
template <class _Tp>
williamr@4
    97
class pthread_allocator : public __stlport_class<pthread_allocator<_Tp> > {
williamr@4
    98
  typedef pthread_alloc _S_Alloc;          // The underlying allocator.
williamr@4
    99
public:
williamr@4
   100
  typedef size_t     size_type;
williamr@4
   101
  typedef ptrdiff_t  difference_type;
williamr@4
   102
  typedef _Tp*       pointer;
williamr@4
   103
  typedef const _Tp* const_pointer;
williamr@4
   104
  typedef _Tp&       reference;
williamr@4
   105
  typedef const _Tp& const_reference;
williamr@4
   106
  typedef _Tp        value_type;
williamr@4
   107
williamr@4
   108
#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
williamr@4
   109
  template <class _NewType> struct rebind {
williamr@4
   110
    typedef pthread_allocator<_NewType> other;
williamr@4
   111
  };
williamr@4
   112
#endif
williamr@4
   113
williamr@4
   114
  pthread_allocator() _STLP_NOTHROW {}
williamr@4
   115
  pthread_allocator(const pthread_allocator<_Tp>& a) _STLP_NOTHROW {}
williamr@4
   116
williamr@4
   117
#if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
williamr@4
   118
  template <class _OtherType> pthread_allocator(const pthread_allocator<_OtherType>&)
williamr@4
   119
    _STLP_NOTHROW {}
williamr@4
   120
#endif
williamr@4
   121
williamr@4
   122
  ~pthread_allocator() _STLP_NOTHROW {}
williamr@4
   123
williamr@4
   124
  pointer address(reference __x) const { return &__x; }
williamr@4
   125
  const_pointer address(const_reference __x) const { return &__x; }
williamr@4
   126
williamr@4
   127
  // __n is permitted to be 0.  The C++ standard says nothing about what
williamr@4
   128
  // the return value is when __n == 0.
williamr@4
   129
  _Tp* allocate(size_type __n, const void* = 0) {
williamr@4
   130
    if (__n > max_size()) {
williamr@4
   131
      __THROW_BAD_ALLOC;
williamr@4
   132
    }
williamr@4
   133
    if (__n != 0) {
williamr@4
   134
      size_type __buf_size = __n * sizeof(value_type);
williamr@4
   135
      _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
williamr@4
   136
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
williamr@4
   137
      if (__ret != 0) {
williamr@4
   138
        memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
williamr@4
   139
      }
williamr@4
   140
#endif
williamr@4
   141
      return __ret;
williamr@4
   142
    }
williamr@4
   143
    else
williamr@4
   144
      return 0;
williamr@4
   145
  }
williamr@4
   146
williamr@4
   147
  void deallocate(pointer __p, size_type __n) {
williamr@4
   148
    _STLP_ASSERT( (__p == 0) == (__n == 0) )
williamr@4
   149
    if (__p != 0) {
williamr@4
   150
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
williamr@4
   151
      memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
williamr@4
   152
#endif
williamr@4
   153
      _S_Alloc::deallocate(__p, __n * sizeof(value_type));
williamr@4
   154
    }
williamr@4
   155
  }
williamr@4
   156
williamr@4
   157
  size_type max_size() const _STLP_NOTHROW
williamr@4
   158
  { return size_t(-1) / sizeof(_Tp); }
williamr@4
   159
williamr@4
   160
  void construct(pointer __p, const _Tp& __val) { _STLP_PLACEMENT_NEW (__p) _Tp(__val); }
williamr@4
   161
  void destroy(pointer _p) { _p->~_Tp(); }
williamr@4
   162
williamr@4
   163
#if defined (_STLP_NO_EXTENSIONS)
williamr@4
   164
  /* STLport extension giving rounded size of an allocated memory buffer
williamr@4
   165
   * This method do not have to be part of a user defined allocator implementation
williamr@4
   166
   * and won't even be called if such a function was granted.
williamr@4
   167
   */
williamr@4
   168
protected:
williamr@4
   169
#endif
williamr@4
   170
  _Tp* allocate(size_type __n, size_type& __allocated_n) {
williamr@4
   171
    if (__n > max_size()) {
williamr@4
   172
      __THROW_BAD_ALLOC;
williamr@4
   173
    }
williamr@4
   174
    if (__n != 0) {
williamr@4
   175
      size_type __buf_size = __n * sizeof(value_type);
williamr@4
   176
      _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
williamr@4
   177
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
williamr@4
   178
      if (__ret != 0) {
williamr@4
   179
        memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
williamr@4
   180
      }
williamr@4
   181
#endif
williamr@4
   182
      __allocated_n = __buf_size / sizeof(value_type);
williamr@4
   183
      return __ret;
williamr@4
   184
    }
williamr@4
   185
    else
williamr@4
   186
      return 0;
williamr@4
   187
  }
williamr@4
   188
};
williamr@4
   189
williamr@4
   190
_STLP_TEMPLATE_NULL
williamr@4
   191
class _STLP_CLASS_DECLSPEC pthread_allocator<void> {
williamr@4
   192
public:
williamr@4
   193
  typedef size_t      size_type;
williamr@4
   194
  typedef ptrdiff_t   difference_type;
williamr@4
   195
  typedef void*       pointer;
williamr@4
   196
  typedef const void* const_pointer;
williamr@4
   197
  typedef void        value_type;
williamr@4
   198
#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
williamr@4
   199
  template <class _NewType> struct rebind {
williamr@4
   200
    typedef pthread_allocator<_NewType> other;
williamr@4
   201
  };
williamr@4
   202
#endif
williamr@4
   203
};
williamr@4
   204
williamr@4
   205
template <class _T1, class _T2>
williamr@4
   206
inline bool operator==(const pthread_allocator<_T1>&,
williamr@4
   207
                       const pthread_allocator<_T2>& a2)
williamr@4
   208
{ return true; }
williamr@4
   209
williamr@4
   210
#ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
williamr@4
   211
template <class _T1, class _T2>
williamr@4
   212
inline bool operator!=(const pthread_allocator<_T1>&,
williamr@4
   213
                       const pthread_allocator<_T2>&)
williamr@4
   214
{ return false; }
williamr@4
   215
#endif
williamr@4
   216
williamr@4
   217
williamr@4
   218
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
williamr@4
   219
williamr@4
   220
#  if defined (_STLP_USE_RAW_SGI_ALLOCATORS)
williamr@4
   221
template <class _Tp>
williamr@4
   222
struct _Alloc_traits<_Tp, _Pthread_alloc>
williamr@4
   223
{ typedef __allocator<_Tp, _Pthread_alloc> allocator_type; };
williamr@4
   224
#  endif
williamr@4
   225
williamr@4
   226
template <class _Tp, class _Atype>
williamr@4
   227
struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
williamr@4
   228
{ typedef pthread_allocator<_Tp> allocator_type; };
williamr@4
   229
williamr@4
   230
#endif
williamr@4
   231
williamr@4
   232
#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
williamr@4
   233
williamr@4
   234
template <class _Tp1, class _Tp2>
williamr@4
   235
inline pthread_allocator<_Tp2>&
williamr@4
   236
__stl_alloc_rebind(pthread_allocator<_Tp1>& __x, const _Tp2*)
williamr@4
   237
{ return (pthread_allocator<_Tp2>&)__x; }
williamr@4
   238
williamr@4
   239
template <class _Tp1, class _Tp2>
williamr@4
   240
inline pthread_allocator<_Tp2>
williamr@4
   241
__stl_alloc_create(pthread_allocator<_Tp1>&, const _Tp2*)
williamr@4
   242
{ return pthread_allocator<_Tp2>(); }
williamr@4
   243
williamr@4
   244
#endif
williamr@4
   245
williamr@4
   246
_STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4
   247
williamr@4
   248
template <class _Tp>
williamr@4
   249
struct __pthread_alloc_type_traits {
williamr@4
   250
  typedef typename _IsSTLportClass<pthread_allocator<_Tp> >::_Ret _STLportAlloc;
williamr@4
   251
  //The default allocator implementation which is recognize thanks to the
williamr@4
   252
  //__stlport_class inheritance is a stateless object so:
williamr@4
   253
  typedef _STLportAlloc has_trivial_default_constructor;
williamr@4
   254
  typedef _STLportAlloc has_trivial_copy_constructor;
williamr@4
   255
  typedef _STLportAlloc has_trivial_assignment_operator;
williamr@4
   256
  typedef _STLportAlloc has_trivial_destructor;
williamr@4
   257
  typedef _STLportAlloc is_POD_type;
williamr@4
   258
};
williamr@4
   259
williamr@4
   260
_STLP_MOVE_TO_STD_NAMESPACE
williamr@4
   261
williamr@4
   262
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
williamr@4
   263
template <class _Tp>
williamr@4
   264
struct __type_traits<pthread_allocator<_Tp> > : _STLP_PRIV __pthread_alloc_type_traits<_Tp> {};
williamr@4
   265
#else
williamr@4
   266
_STLP_TEMPLATE_NULL
williamr@4
   267
struct __type_traits<pthread_allocator<char> > : _STLP_PRIV __pthread_alloc_type_traits<char> {};
williamr@4
   268
#  if defined (_STLP_HAS_WCHAR_T)
williamr@4
   269
_STLP_TEMPLATE_NULL
williamr@4
   270
struct __type_traits<pthread_allocator<wchar_t> > : _STLP_PRIV __pthread_alloc_type_traits<wchar_t> {};
williamr@4
   271
#  endif
williamr@4
   272
#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
williamr@4
   273
_STLP_TEMPLATE_NULL
williamr@4
   274
struct __type_traits<pthread_allocator<void*> > : _STLP_PRIV __pthread_alloc_type_traits<void*> {};
williamr@4
   275
#  endif
williamr@4
   276
#endif
williamr@4
   277
williamr@4
   278
//
williamr@4
   279
// per_thread_allocator<> : this allocator always return memory to the same thread
williamr@4
   280
// it was allocated from.
williamr@4
   281
//
williamr@4
   282
williamr@4
   283
template <class _Tp>
williamr@4
   284
class per_thread_allocator {
williamr@4
   285
  typedef pthread_alloc _S_Alloc;          // The underlying allocator.
williamr@4
   286
  typedef pthread_alloc::__state_type __state_type;
williamr@4
   287
public:
williamr@4
   288
  typedef size_t     size_type;
williamr@4
   289
  typedef ptrdiff_t  difference_type;
williamr@4
   290
  typedef _Tp*       pointer;
williamr@4
   291
  typedef const _Tp* const_pointer;
williamr@4
   292
  typedef _Tp&       reference;
williamr@4
   293
  typedef const _Tp& const_reference;
williamr@4
   294
  typedef _Tp        value_type;
williamr@4
   295
williamr@4
   296
#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
williamr@4
   297
  template <class _NewType> struct rebind {
williamr@4
   298
    typedef per_thread_allocator<_NewType> other;
williamr@4
   299
  };
williamr@4
   300
#endif
williamr@4
   301
williamr@4
   302
  per_thread_allocator() _STLP_NOTHROW {
williamr@4
   303
    _M_state = _S_Alloc::_S_get_per_thread_state();
williamr@4
   304
  }
williamr@4
   305
  per_thread_allocator(const per_thread_allocator<_Tp>& __a) _STLP_NOTHROW : _M_state(__a._M_state){}
williamr@4
   306
williamr@4
   307
#if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
williamr@4
   308
  template <class _OtherType> per_thread_allocator(const per_thread_allocator<_OtherType>& __a)
williamr@4
   309
    _STLP_NOTHROW : _M_state(__a._M_state) {}
williamr@4
   310
#endif
williamr@4
   311
williamr@4
   312
  ~per_thread_allocator() _STLP_NOTHROW {}
williamr@4
   313
williamr@4
   314
  pointer address(reference __x) const { return &__x; }
williamr@4
   315
  const_pointer address(const_reference __x) const { return &__x; }
williamr@4
   316
williamr@4
   317
  // __n is permitted to be 0.  The C++ standard says nothing about what
williamr@4
   318
  // the return value is when __n == 0.
williamr@4
   319
  _Tp* allocate(size_type __n, const void* = 0) {
williamr@4
   320
    if (__n > max_size()) {
williamr@4
   321
      __THROW_BAD_ALLOC;
williamr@4
   322
    }
williamr@4
   323
    if (__n != 0) {
williamr@4
   324
      size_type __buf_size = __n * sizeof(value_type);
williamr@4
   325
      _Tp* __ret = __REINTERPRET_CAST(_Tp*, _S_Alloc::allocate(__buf_size, _M_state));
williamr@4
   326
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
williamr@4
   327
      if (__ret != 0) {
williamr@4
   328
        memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
williamr@4
   329
      }
williamr@4
   330
#endif
williamr@4
   331
      return __ret;
williamr@4
   332
    }
williamr@4
   333
    else
williamr@4
   334
      return 0;
williamr@4
   335
  }
williamr@4
   336
williamr@4
   337
  void deallocate(pointer __p, size_type __n) {
williamr@4
   338
    _STLP_ASSERT( (__p == 0) == (__n == 0) )
williamr@4
   339
    if (__p != 0) {
williamr@4
   340
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
williamr@4
   341
      memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
williamr@4
   342
#endif
williamr@4
   343
      _S_Alloc::deallocate(__p, __n * sizeof(value_type), _M_state);
williamr@4
   344
    }
williamr@4
   345
  }
williamr@4
   346
williamr@4
   347
  size_type max_size() const _STLP_NOTHROW
williamr@4
   348
  { return size_t(-1) / sizeof(_Tp); }
williamr@4
   349
williamr@4
   350
  void construct(pointer __p, const _Tp& __val) { _STLP_PLACEMENT_NEW (__p) _Tp(__val); }
williamr@4
   351
  void destroy(pointer _p) { _p->~_Tp(); }
williamr@4
   352
williamr@4
   353
  // state is being kept here
williamr@4
   354
  __state_type* _M_state;
williamr@4
   355
williamr@4
   356
#if defined (_STLP_NO_EXTENSIONS)
williamr@4
   357
  /* STLport extension giving rounded size of an allocated memory buffer
williamr@4
   358
   * This method do not have to be part of a user defined allocator implementation
williamr@4
   359
   * and won't even be called if such a function was granted.
williamr@4
   360
   */
williamr@4
   361
protected:
williamr@4
   362
#endif
williamr@4
   363
  _Tp* allocate(size_type __n, size_type& __allocated_n) {
williamr@4
   364
    if (__n > max_size()) {
williamr@4
   365
      __THROW_BAD_ALLOC;
williamr@4
   366
    }
williamr@4
   367
    if (__n != 0) {
williamr@4
   368
      size_type __buf_size = __n * sizeof(value_type);
williamr@4
   369
      _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size, _M_state));
williamr@4
   370
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
williamr@4
   371
      if (__ret != 0) {
williamr@4
   372
        memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
williamr@4
   373
      }
williamr@4
   374
#endif
williamr@4
   375
      __allocated_n = __buf_size / sizeof(value_type);
williamr@4
   376
      return __ret;
williamr@4
   377
    }
williamr@4
   378
    else
williamr@4
   379
      return 0;
williamr@4
   380
  }
williamr@4
   381
};
williamr@4
   382
williamr@4
   383
_STLP_TEMPLATE_NULL
williamr@4
   384
class _STLP_CLASS_DECLSPEC per_thread_allocator<void> {
williamr@4
   385
public:
williamr@4
   386
  typedef size_t      size_type;
williamr@4
   387
  typedef ptrdiff_t   difference_type;
williamr@4
   388
  typedef void*       pointer;
williamr@4
   389
  typedef const void* const_pointer;
williamr@4
   390
  typedef void        value_type;
williamr@4
   391
#ifdef _STLP_MEMBER_TEMPLATE_CLASSES
williamr@4
   392
  template <class _NewType> struct rebind {
williamr@4
   393
    typedef per_thread_allocator<_NewType> other;
williamr@4
   394
  };
williamr@4
   395
#endif
williamr@4
   396
};
williamr@4
   397
williamr@4
   398
template <class _T1, class _T2>
williamr@4
   399
inline bool operator==(const per_thread_allocator<_T1>& __a1,
williamr@4
   400
                       const per_thread_allocator<_T2>& __a2)
williamr@4
   401
{ return __a1._M_state == __a2._M_state; }
williamr@4
   402
williamr@4
   403
#ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
williamr@4
   404
template <class _T1, class _T2>
williamr@4
   405
inline bool operator!=(const per_thread_allocator<_T1>& __a1,
williamr@4
   406
                       const per_thread_allocator<_T2>& __a2)
williamr@4
   407
{ return __a1._M_state != __a2._M_state; }
williamr@4
   408
#endif
williamr@4
   409
williamr@4
   410
williamr@4
   411
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
williamr@4
   412
williamr@4
   413
template <class _Tp, class _Atype>
williamr@4
   414
struct _Alloc_traits<_Tp, per_thread_allocator<_Atype> >
williamr@4
   415
{ typedef per_thread_allocator<_Tp> allocator_type; };
williamr@4
   416
williamr@4
   417
#endif
williamr@4
   418
williamr@4
   419
#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
williamr@4
   420
williamr@4
   421
template <class _Tp1, class _Tp2>
williamr@4
   422
inline per_thread_allocator<_Tp2>&
williamr@4
   423
__stl_alloc_rebind(per_thread_allocator<_Tp1>& __x, const _Tp2*)
williamr@4
   424
{ return (per_thread_allocator<_Tp2>&)__x; }
williamr@4
   425
williamr@4
   426
template <class _Tp1, class _Tp2>
williamr@4
   427
inline per_thread_allocator<_Tp2>
williamr@4
   428
__stl_alloc_create(per_thread_allocator<_Tp1>&, const _Tp2*)
williamr@4
   429
{ return per_thread_allocator<_Tp2>(); }
williamr@4
   430
williamr@4
   431
#endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
williamr@4
   432
williamr@4
   433
_STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4
   434
williamr@4
   435
template <class _Tp>
williamr@4
   436
struct __perthread_alloc_type_traits {
williamr@4
   437
  typedef typename _IsSTLportClass<per_thread_allocator<_Tp> >::_Ret _STLportAlloc;
williamr@4
   438
  //The default allocator implementation which is recognize thanks to the
williamr@4
   439
  //__stlport_class inheritance is a stateless object so:
williamr@4
   440
  typedef __false_type has_trivial_default_constructor;
williamr@4
   441
  typedef _STLportAlloc has_trivial_copy_constructor;
williamr@4
   442
  typedef _STLportAlloc has_trivial_assignment_operator;
williamr@4
   443
  typedef _STLportAlloc has_trivial_destructor;
williamr@4
   444
  typedef __false_type is_POD_type;
williamr@4
   445
};
williamr@4
   446
williamr@4
   447
_STLP_MOVE_TO_STD_NAMESPACE
williamr@4
   448
williamr@4
   449
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
williamr@4
   450
template <class _Tp>
williamr@4
   451
struct __type_traits<per_thread_allocator<_Tp> > : _STLP_PRIV __perthread_alloc_type_traits<_Tp> {};
williamr@4
   452
#else
williamr@4
   453
_STLP_TEMPLATE_NULL
williamr@4
   454
struct __type_traits<per_thread_allocator<char> > : _STLP_PRIV __perthread_alloc_type_traits<char> {};
williamr@4
   455
#  if defined (_STLP_HAS_WCHAR_T)
williamr@4
   456
_STLP_TEMPLATE_NULL
williamr@4
   457
struct __type_traits<per_thread_allocator<wchar_t> > : _STLP_PRIV __perthread_alloc_type_traits<wchar_t> {};
williamr@4
   458
#  endif
williamr@4
   459
#  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
williamr@4
   460
_STLP_TEMPLATE_NULL
williamr@4
   461
struct __type_traits<per_thread_allocator<void*> > : _STLP_PRIV __perthread_alloc_type_traits<void*> {};
williamr@4
   462
#  endif
williamr@4
   463
#endif
williamr@4
   464
williamr@4
   465
williamr@4
   466
_STLP_END_NAMESPACE
williamr@4
   467
williamr@4
   468
#endif /* _STLP_PTHREAD_ALLOC */
williamr@4
   469
williamr@4
   470
// Local Variables:
williamr@4
   471
// mode:C++
williamr@4
   472
// End: