williamr@2: template williamr@2: class __simple_alloc { williamr@2: typedef _Alloc __alloc_type; williamr@2: public: williamr@2: typedef typename _Alloc::value_type __alloc_value_type; williamr@2: typedef _Tp value_type; williamr@2: static size_t _STLP_CALL __chunk(size_t __n) { williamr@2: return (sizeof(__alloc_value_type)==sizeof(value_type)) ? __n : williamr@2: ((__n*sizeof(value_type)+sizeof(__alloc_value_type)-1)/sizeof(__alloc_value_type)); williamr@2: } williamr@2: static _Tp* _STLP_CALL allocate(size_t __n) { return 0 == __n ? 0 : (_Tp*) __alloc_type::allocate(__chunk(__n)); } williamr@2: static void _STLP_CALL deallocate(_Tp * __p, size_t __n) { williamr@2: __alloc_type::deallocate((__alloc_value_type*)__p, __chunk(__n)); } williamr@2: }; williamr@2: williamr@2: // Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) williamr@2: // into a standard-conforming allocator. Note that this adaptor does williamr@2: // *not* assume that all objects of the underlying alloc class are williamr@2: // identical, nor does it assume that all of the underlying alloc's williamr@2: // member functions are static member functions. Note, also, that williamr@2: // __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. williamr@2: williamr@2: template williamr@2: struct __allocator : public _Alloc { williamr@2: typedef _Alloc __underlying_alloc; williamr@2: williamr@2: typedef size_t size_type; williamr@2: typedef ptrdiff_t difference_type; williamr@2: typedef _Tp* pointer; williamr@2: typedef const _Tp* const_pointer; williamr@2: typedef _Tp& reference; williamr@2: typedef const _Tp& const_reference; williamr@2: typedef _Tp value_type; williamr@2: williamr@2: # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) williamr@2: template struct rebind { williamr@2: typedef __allocator<_Tp1, _Alloc> other; williamr@2: }; williamr@2: # endif williamr@2: __allocator() _STLP_NOTHROW {} williamr@2: __allocator(const _Alloc& ) _STLP_NOTHROW {} williamr@2: __allocator(const __allocator<_Tp, _Alloc>& __a) _STLP_NOTHROW williamr@2: : _Alloc(__a) {} williamr@2: # if defined (_STLP_MEMBER_TEMPLATES) && defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) williamr@2: template williamr@2: __allocator(const __allocator<_Tp1, _Alloc>& __a) _STLP_NOTHROW williamr@2: : _Alloc(__a) {} williamr@2: # endif williamr@2: # ifdef _STLP_TRIVIAL_DESTRUCTOR_BUG williamr@2: ~__allocator() _STLP_NOTHROW {} williamr@2: # endif williamr@2: pointer address(reference __x) const { return &__x; } williamr@2: williamr@2: # if !defined (__WATCOM_CPLUSPLUS__) williamr@2: const_pointer address(const_reference __x) const { return &__x; } williamr@2: # endif williamr@2: williamr@2: // __n is permitted to be 0. williamr@2: _Tp* allocate(size_type __n, const void* = 0) { williamr@2: if (__n > max_size()) williamr@2: __THROW_BAD_ALLOC; williamr@2: return __n != 0 williamr@2: ? __STATIC_CAST(_Tp*,__underlying_alloc::allocate(__n * sizeof(_Tp))) williamr@2: : 0; williamr@2: } williamr@2: williamr@2: // __p is not permitted to be a null pointer. williamr@2: void deallocate(pointer __p, size_type __n) williamr@2: { if (__p) __underlying_alloc::deallocate(__p, __n * sizeof(_Tp)); } williamr@2: williamr@2: size_type max_size() const _STLP_NOTHROW williamr@2: { return size_t(-1) / sizeof(_Tp); } williamr@2: williamr@2: void construct(pointer __p, const_reference __val) { _STLP_STD::_Copy_Construct(__p, __val); } williamr@2: void destroy(pointer __p) { _STLP_STD::_Destroy(__p); } williamr@2: williamr@2: const __underlying_alloc& __get_underlying_alloc() const { return *this; } williamr@2: }; williamr@2: williamr@2: #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION williamr@2: template williamr@2: class __allocator { williamr@2: typedef size_t size_type; williamr@2: typedef ptrdiff_t difference_type; williamr@2: typedef void* pointer; williamr@2: typedef const void* const_pointer; williamr@2: typedef void value_type; williamr@2: #ifdef _STLP_MEMBER_TEMPLATE_CLASSES williamr@2: template struct rebind { williamr@2: typedef __allocator<_Tp1, _Alloc> other; williamr@2: }; williamr@2: #endif williamr@2: }; williamr@2: #endif williamr@2: williamr@2: template williamr@2: inline bool _STLP_CALL operator==(const __allocator<_Tp, _Alloc>& __a1, williamr@2: const __allocator<_Tp, _Alloc>& __a2) williamr@2: { williamr@2: return __a1.__get_underlying_alloc() == __a2.__get_underlying_alloc(); williamr@2: } williamr@2: williamr@2: #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE williamr@2: template williamr@2: inline bool _STLP_CALL operator!=(const __allocator<_Tp, _Alloc>& __a1, williamr@2: const __allocator<_Tp, _Alloc>& __a2) williamr@2: { williamr@2: return __a1.__get_underlying_alloc() != __a2.__get_underlying_alloc(); williamr@2: } williamr@2: #endif /* _STLP_FUNCTION_TMPL_PARTIAL_ORDER */ williamr@2: williamr@2: williamr@2: // Comparison operators for all of the predifined SGI-style allocators. williamr@2: // This ensures that __allocator (for example) will williamr@2: // work correctly. williamr@2: williamr@2: #ifndef _STLP_NON_TYPE_TMPL_PARAM_BUG williamr@2: inline bool _STLP_CALL operator==(const __malloc_alloc&, const __malloc_alloc&) williamr@2: { return true; } williamr@2: williamr@2: # ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER williamr@2: inline bool _STLP_CALL operator!=(const __malloc_alloc&, const __malloc_alloc&) williamr@2: { return false; } williamr@2: # endif williamr@2: williamr@2: inline bool _STLP_CALL operator==(const __new_alloc&, const __new_alloc&) { return true; } williamr@2: williamr@2: # ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE williamr@2: inline bool _STLP_CALL operator!=(const __new_alloc&, const __new_alloc&) { return false; } williamr@2: # endif williamr@2: williamr@2: # if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: inline bool _STLP_CALL operator==(const __node_alloc&, williamr@2: const __node_alloc&) williamr@2: { return true; } williamr@2: williamr@2: # if defined( _STLP_FUNCTION_TMPL_PARTIAL_ORDER ) williamr@2: williamr@2: inline bool _STLP_CALL operator!=(const __node_alloc&, williamr@2: const __node_alloc&) williamr@2: { return false; } williamr@2: # endif williamr@2: # endif williamr@2: williamr@2: #endif /* _STLP_NON_TYPE_TMPL_PARAM_BUG */ williamr@2: williamr@2: template williamr@2: inline bool _STLP_CALL operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&) { return true; } williamr@2: # ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE williamr@2: template williamr@2: inline bool _STLP_CALL operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&) { return false; } williamr@2: # endif williamr@2: williamr@2: #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) williamr@2: williamr@2: // Versions for the predefined SGI-style allocators. williamr@2: template williamr@2: struct _Alloc_traits<_Tp, __malloc_alloc> { williamr@2: typedef __allocator<_Tp, __malloc_alloc> allocator_type; williamr@2: }; williamr@2: williamr@2: # if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: template williamr@2: struct _Alloc_traits<_Tp, __node_alloc> { williamr@2: typedef __allocator<_Tp, __node_alloc> allocator_type; williamr@2: }; williamr@2: # endif williamr@2: williamr@2: template williamr@2: struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> > { williamr@2: typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; williamr@2: }; williamr@2: williamr@2: // Versions for the __allocator adaptor used with the predefined williamr@2: // SGI-style allocators. williamr@2: williamr@2: template williamr@2: struct _Alloc_traits<_Tp, __allocator<_Tp1, _Alloc > > { williamr@2: typedef __allocator<_Tp, _Alloc > allocator_type; williamr@2: }; williamr@2: williamr@2: #endif williamr@2: williamr@2: #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) williamr@2: williamr@2: // Versions for the predefined SGI-style allocators. williamr@2: williamr@2: williamr@2: # if defined (_STLP_NON_TYPE_TMPL_PARAM_BUG) williamr@2: williamr@2: typedef __malloc_alloc __malloc_alloc_dfl; williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp, __malloc_alloc_dfl >& _STLP_CALL williamr@2: __stl_alloc_rebind(__malloc_alloc_dfl& __a, const _Tp*) { williamr@2: return (__allocator<_Tp, __malloc_alloc_dfl >&)__a; williamr@2: } williamr@2: williamr@2: # if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: template williamr@2: inline __allocator<_Tp, __node_alloc>& _STLP_CALL williamr@2: __stl_alloc_rebind(__node_alloc& __a, const _Tp*) { williamr@2: return (__allocator<_Tp, __node_alloc>&)__a; williamr@2: } williamr@2: # endif williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp, __malloc_alloc_dfl > _STLP_CALL williamr@2: __stl_alloc_create(const __malloc_alloc_dfl&, const _Tp*) { williamr@2: return __allocator<_Tp, __malloc_alloc_dfl > (); williamr@2: } williamr@2: williamr@2: # if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: template williamr@2: inline __allocator<_Tp, __node_alloc> _STLP_CALL williamr@2: __stl_alloc_create(const __node_alloc&, const _Tp*) { williamr@2: return __allocator<_Tp, __node_alloc>(); williamr@2: } williamr@2: williamr@2: # endif williamr@2: williamr@2: # else williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp, __malloc_alloc>& _STLP_CALL williamr@2: __stl_alloc_rebind(__malloc_alloc& __a, const _Tp*) { williamr@2: return (__allocator<_Tp, __malloc_alloc>&)__a; williamr@2: } williamr@2: williamr@2: # if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: template williamr@2: inline __allocator<_Tp, __node_alloc>& _STLP_CALL williamr@2: __stl_alloc_rebind(__node_alloc& __a, const _Tp*) { williamr@2: return (__allocator<_Tp, __node_alloc>&)__a; williamr@2: } williamr@2: # endif williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp, __malloc_alloc> _STLP_CALL williamr@2: __stl_alloc_create(const __malloc_alloc&, const _Tp*) { williamr@2: return __allocator<_Tp, __malloc_alloc>(); williamr@2: } williamr@2: williamr@2: # if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: template williamr@2: inline __allocator<_Tp, __node_alloc> _STLP_CALL williamr@2: __stl_alloc_create(const __node_alloc&, const _Tp*) { williamr@2: return __allocator<_Tp, __node_alloc>(); williamr@2: } williamr@2: # endif williamr@2: williamr@2: # endif williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp, __debug_alloc<_Alloc> > _STLP_CALL williamr@2: __stl_alloc_create(const __debug_alloc<_Alloc>&, const _Tp*) { williamr@2: return __allocator<_Tp, __debug_alloc<_Alloc> >(); williamr@2: } williamr@2: template williamr@2: inline __allocator<_Tp, __debug_alloc<_Alloc> >& _STLP_CALL williamr@2: __stl_alloc_rebind(__debug_alloc<_Alloc>& __a, const _Tp*) { williamr@2: return (__allocator<_Tp, __debug_alloc<_Alloc> >&)__a; williamr@2: } williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp, __new_alloc > _STLP_CALL williamr@2: __stl_alloc_create(const __new_alloc&, const _Tp*) { williamr@2: return __allocator<_Tp, __new_alloc >(); williamr@2: } williamr@2: template williamr@2: inline __allocator<_Tp, __new_alloc >& _STLP_CALL williamr@2: __stl_alloc_rebind(__new_alloc& __a, const _Tp*) { williamr@2: return (__allocator<_Tp, __new_alloc >&)__a; williamr@2: } williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp2, _Alloc>& _STLP_CALL williamr@2: __stl_alloc_rebind(__allocator<_Tp1, _Alloc>& __a, const _Tp2*) { williamr@2: return (__allocator<_Tp2, _Alloc>&)__a; williamr@2: } williamr@2: williamr@2: template williamr@2: inline __allocator<_Tp2, _Alloc> _STLP_CALL williamr@2: __stl_alloc_create(const __allocator<_Tp1, _Alloc>&, const _Tp2*) { williamr@2: return __allocator<_Tp2, _Alloc>(); williamr@2: } williamr@2: #endif