diff -r e1b950c65cb4 -r 837f303aceeb epoc32/include/stdapis/stlportv5/stl/_alloc.h --- a/epoc32/include/stdapis/stlportv5/stl/_alloc.h Wed Mar 31 12:27:01 2010 +0100 +++ b/epoc32/include/stdapis/stlportv5/stl/_alloc.h Wed Mar 31 12:33:34 2010 +0100 @@ -1,4 +1,5 @@ /* + * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. @@ -6,13 +7,13 @@ * Copyright (c) 1997 * Moscow Center for SPARC Technology * - * Copyright (c) 1999 + * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * - * Permission to use or copy this software for any purpose is hereby granted + * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was @@ -27,118 +28,107 @@ #ifndef _STLP_INTERNAL_ALLOC_H #define _STLP_INTERNAL_ALLOC_H -# ifndef _STLP_CSTDDEF -# include -# endif - -#if !defined (_STLP_DEBUG_H) && (defined (_STLP_DEBUG) || defined (_STLP_ASSERTIONS)) -# include +#ifndef _STLP_INTERNAL_CSTDDEF +# include #endif -# ifndef _STLP_CSTDLIB -# include -# endif -# ifndef _STLP_CSTRING -# include -# endif +#if !defined (_STLP_DEBUG_H) && (defined(_STLP_DEBUG) || defined(_STLP_ASSERTIONS) || defined(_STLP_DEBUG_ALLOC)) +# include +#endif -# ifndef __THROW_BAD_ALLOC +#ifndef _STLP_INTERNAL_CSTDLIB +# include +#endif + +#ifndef _STLP_INTERNAL_CSTRING +# include +#endif + +#ifndef _STLP_INTERNAL_ALGOBASE_H +# include +#endif + +#ifndef __THROW_BAD_ALLOC # if !defined(_STLP_USE_EXCEPTIONS) -# if !defined (_STLP_CSTDIO) -# include -# endif -# if !defined (_STLP_CSTDLIB) -# include -# endif -# define __THROW_BAD_ALLOC puts("out of memory\n"); exit(1) -# else /* !defined(_STLP_USE_EXCEPTIONS) */ -# define __THROW_BAD_ALLOC throw _STLP_STD::bad_alloc() -# endif /* !defined(_STLP_USE_EXCEPTIONS) */ -# endif /* __THROW_BAD_ALLOC */ +# ifndef _STLP_INTERNAL_CSTDIO +# include +# endif +# define __THROW_BAD_ALLOC puts("out of memory\n"); exit(1) +# else +# define __THROW_BAD_ALLOC throw _STLP_STD::bad_alloc() +# endif +#endif -# ifndef _STLP_INTERNAL_NEW_HEADER +#ifndef _STLP_INTERNAL_NEW_HEADER # include -# endif - -// #if ! defined (__SYMBIAN32__) -#if /* defined (_STLP_THREADS) && */ ! defined (_STLP_INTERNAL_THREADS_H) -# include -// #endif #endif #ifndef _STLP_INTERNAL_CONSTRUCT_H -# include +# include #endif -#ifndef __ALLOC -# define __ALLOC __sgi_alloc -#endif - -# ifndef __RESTRICT -# define __RESTRICT -# endif - -#if defined (_STLP_THREADS) || (defined(_STLP_OWN_IOSTREAMS) && ! defined (_STLP_NO_THREADS) && ! defined (_NOTHREADS) ) -# define _STLP_NODE_ALLOCATOR_THREADS true -#else -# define _STLP_NODE_ALLOCATOR_THREADS false +#if !defined (__ALLOC) +# define __ALLOC __sgi_alloc #endif _STLP_BEGIN_NAMESPACE -# if defined (_STLP_USE_RAW_SGI_ALLOCATORS) +#if defined (_STLP_USE_RAW_SGI_ALLOCATORS) template struct __allocator; -# endif - -#ifndef _STLP_NO_NODE_ALLOC +#endif // Malloc-based allocator. Typically slower than default alloc below. // Typically thread-safe and more storage efficient. +#if !defined (_STLP_USE_NO_IOSTREAMS) typedef void (* __oom_handler_type)(); +#endif -template -class __malloc_alloc { -private: - static void* _STLP_CALL _S_oom_malloc(size_t); - static __oom_handler_type __oom_handler; +class _STLP_CLASS_DECLSPEC __malloc_alloc { public: // this one is needed for proper simple_alloc wrapping typedef char value_type; -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) +#if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) template struct rebind { - typedef __allocator<_Tp1, __malloc_alloc<__inst> > other; + typedef __allocator<_Tp1, __malloc_alloc> other; }; -# endif - static void* _STLP_CALL allocate(size_t __n) { - void* __result = malloc(__n); - if (0 == __result) __result = _S_oom_malloc(__n); +#endif + static void* _STLP_CALL allocate(size_t& __n) +#if !defined (_STLP_USE_NO_IOSTREAMS) + ; +#else + { + void *__result = malloc(__n); +# if defined (_STLP_MALLOC_USABLE_SIZE) + if (__result != 0) { + __n = _STLP_MALLOC_USABLE_SIZE(__result); + } +# endif + if (__result == 0) { + __THROW_BAD_ALLOC; + } return __result; } +#endif + static void _STLP_CALL deallocate(void* __p, size_t /* __n */) { free((char*)__p); } - static __oom_handler_type _STLP_CALL set_malloc_handler(__oom_handler_type __f) { - __oom_handler_type __old = __oom_handler; - __oom_handler = __f; - return(__old); - } +#if !defined (_STLP_USE_NO_IOSTREAMS) + static __oom_handler_type _STLP_CALL set_malloc_handler(__oom_handler_type __f); +#endif }; -# endif - // New-based allocator. Typically slower than default alloc below. // Typically thread-safe and more storage efficient. class _STLP_CLASS_DECLSPEC __new_alloc { public: // this one is needed for proper simple_alloc wrapping typedef char value_type; -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined(_STLP_USE_RAW_SGI_ALLOCATORS) +#if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) template struct rebind { typedef __allocator<_Tp1, __new_alloc > other; }; -# endif - static void* _STLP_CALL allocate(size_t __n) { - return __stl_new(__n); - } +#endif + static void* _STLP_CALL allocate(size_t __n) { return __stl_new(__n); } static void _STLP_CALL deallocate(void* __p, size_t) { __stl_delete(__p); } }; @@ -162,128 +152,121 @@ _STLP_UINT32_T _M_size; }; // that is 8 bytes for sure // Sunpro CC has bug on enums, so extra_before/after set explicitly - enum { __pad=8, __magic=0xdeba, __deleted_magic = 0xdebd, - __shred_byte= _STLP_SHRED_BYTE - }; + enum { __pad = 8, __magic = 0xdeba, __deleted_magic = 0xdebd, + __shred_byte = _STLP_SHRED_BYTE }; enum { __extra_before = 16, __extra_after = 8 }; // Size of space used to store size. Note // that this must be large enough to preserve // alignment. static size_t _STLP_CALL __extra_before_chunk() { - return (long)__extra_before/sizeof(value_type)+ - (size_t)((long)__extra_before%sizeof(value_type)>0); + return (long)__extra_before / sizeof(value_type) + + (size_t)((long)__extra_before % sizeof(value_type) > 0); } static size_t _STLP_CALL __extra_after_chunk() { - return (long)__extra_after/sizeof(value_type)+ - (size_t)((long)__extra_after%sizeof(value_type)>0); + return (long)__extra_after / sizeof(value_type) + + (size_t)((long)__extra_after % sizeof(value_type) > 0); } public: -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) +#if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) template struct rebind { typedef __allocator< _Tp1, __debug_alloc<_Alloc> > other; }; -# endif +#endif __debug_alloc() {} ~__debug_alloc() {} - static void * _STLP_CALL allocate(size_t); + static void* _STLP_CALL allocate(size_t); static void _STLP_CALL deallocate(void *, size_t); }; -# if defined(__OS400__) -enum {_ALIGN = 16, _ALIGN_SHIFT=4, _MAX_BYTES = 256}; -# define _STLP_NFREELISTS 16 -# else -enum {_ALIGN = 8, _ALIGN_SHIFT=3, _MAX_BYTES = 128}; -# define _STLP_NFREELISTS 16 -# endif /* __OS400__ */ +# if defined (__OS400__) || defined (_WIN64) +enum {_ALIGN = 16, _ALIGN_SHIFT = 4, _MAX_BYTES = 256}; +# else +enum {_ALIGN = 8, _ALIGN_SHIFT = 3, _MAX_BYTES = 128}; +# endif /* __OS400__ */ -#ifndef _STLP_NO_NODE_ALLOC - +#if !defined (_STLP_USE_NO_IOSTREAMS) // Default node allocator. // With a reasonable compiler, this should be roughly as fast as the // original STL class-specific allocators, but with less fragmentation. -// Default_alloc_template parameters are experimental and MAY -// DISAPPEAR in the future. Clients should just use alloc for now. -// -// Important implementation properties: -// 1. If the client request an object of size > _MAX_BYTES, the resulting -// object will be obtained directly from malloc. -// 2. In all other cases, we allocate an object of size exactly -// _S_round_up(requested_size). Thus the client has enough size -// information that we can return the object to the proper free list -// without permanently losing part of the object. -// +class _STLP_CLASS_DECLSPEC __node_alloc { + _STLP_DECLSPEC static void * _STLP_CALL _M_allocate(size_t& __n); + /* __p may not be 0 */ + _STLP_DECLSPEC static void _STLP_CALL _M_deallocate(void *__p, size_t __n); -// The first template parameter specifies whether more than one thread -// may use this allocator. It is safe to allocate an object from -// one instance of a default_alloc and deallocate it with another -// one. This effectively transfers its ownership to the second one. -// This may have undesirable effects on reference locality. -// The second parameter is unreferenced and serves only to allow the -// creation of multiple default_alloc instances. - -class _STLP_CLASS_DECLSPEC _Node_alloc_obj { -public: - _Node_alloc_obj * _M_free_list_link; -}; - -template -class __node_alloc { - _STLP_PRIVATE: - static inline size_t _STLP_CALL _S_round_up(size_t __bytes) { return (((__bytes) + (size_t)_ALIGN-1) & ~((size_t)_ALIGN - 1)); } - typedef _Node_alloc_obj _Obj; -private: - // Returns an object of size __n, and optionally adds to size __n free list. - static void* _STLP_CALL _S_refill(size_t __n); - // Allocates a chunk for nobjs of size size. nobjs may be reduced - // if it is inconvenient to allocate the requested number. - static char* _STLP_CALL _S_chunk_alloc(size_t __p_size, int& __nobjs); - // Chunk allocation state. - static _Node_alloc_obj * _STLP_VOLATILE _S_free_list[_STLP_NFREELISTS]; - static char* _S_start_free; - static char* _S_end_free; - static size_t _S_heap_size; - static void * _STLP_CALL _M_allocate(size_t __n); - /* __p may not be 0 */ - static void _STLP_CALL _M_deallocate(void *__p, size_t __n); public: // this one is needed for proper simple_alloc wrapping typedef char value_type; -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) +# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_USE_RAW_SGI_ALLOCATORS) template struct rebind { - typedef __allocator<_Tp1, __node_alloc<__threads, __inst> > other; + typedef __allocator<_Tp1, __node_alloc> other; }; -# endif +# endif /* __n must be > 0 */ - static void * _STLP_CALL allocate(size_t __n) { -return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); } + static void* _STLP_CALL allocate(size_t& __n) + { return (__n > (size_t)_MAX_BYTES) ? __stl_new(__n) : _M_allocate(__n); } /* __p may not be 0 */ - static void _STLP_CALL deallocate(void *__p, size_t __n) { -if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); } + static void _STLP_CALL deallocate(void *__p, size_t __n) + { if (__n > (size_t)_MAX_BYTES) __stl_delete(__p); else _M_deallocate(__p, __n); } }; -# if defined (_STLP_USE_TEMPLATE_EXPORT) -_STLP_EXPORT_TEMPLATE_CLASS __malloc_alloc<0>; -_STLP_EXPORT_TEMPLATE_CLASS __node_alloc<_STLP_NODE_ALLOCATOR_THREADS, 0>; -# endif /* _STLP_USE_TEMPLATE_EXPORT */ -typedef __node_alloc<_STLP_NODE_ALLOCATOR_THREADS, 0> _Node_alloc; -# if defined (_STLP_USE_TEMPLATE_EXPORT) -_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<_Node_alloc>; +# if defined (_STLP_USE_TEMPLATE_EXPORT) +_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__node_alloc>; +# endif + +#endif /* _STLP_USE_NO_IOSTREAMS */ + +#if defined (_STLP_USE_TEMPLATE_EXPORT) _STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__new_alloc>; -_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__malloc_alloc<0> >; -# endif - +_STLP_EXPORT_TEMPLATE_CLASS __debug_alloc<__malloc_alloc>; #endif -# if defined (_STLP_USE_PERTHREAD_ALLOC) +/* macro to convert the allocator for initialization + * not using MEMBER_TEMPLATE_CLASSES as it should work given template constructor */ +#if defined (_STLP_MEMBER_TEMPLATES) || ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) +/* if _STLP_NO_TEMPLATE_CONVERSIONS is set, the member template constructor is + * not used implicitly to convert allocator parameter, so let us do it explicitly */ +# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_NO_TEMPLATE_CONVERSIONS) +# define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0) +# else +# define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __a +# endif +/* else convert, but only if partial specialization works, since else + * Container::allocator_type won't be different */ +#else +# define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0) +#endif /* _STLP_MEMBER_TEMPLATES || !_STLP_CLASS_PARTIAL_SPECIALIZATION */ + +// Another allocator adaptor: _Alloc_traits. This serves two +// purposes. First, make it possible to write containers that can use +// either SGI-style allocators or standard-conforming allocator. + +// The fully general version. +template +struct _Alloc_traits { + typedef _Allocator _Orig; +#if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) + typedef typename _Allocator::_STLP_TEMPLATE rebind<_Tp> _Rebind_type; + typedef typename _Rebind_type::other allocator_type; + static allocator_type create_allocator(const _Orig& __a) + { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); } +#else + // this is not actually true, used only to pass this type through + // to dynamic overload selection in _STLP_alloc_proxy methods + typedef _Allocator allocator_type; +#endif /* !_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */ +}; + +#if defined (_STLP_USE_PERTHREAD_ALLOC) _STLP_END_NAMESPACE + // include additional header here -# include +# include + _STLP_BEGIN_NAMESPACE -# if defined ( _STLP_DEBUG_ALLOC ) +# if defined (_STLP_DEBUG_ALLOC) typedef __debug_alloc<__pthread_alloc> __sgi_alloc; # else typedef __pthread_alloc __sgi_alloc; @@ -292,45 +275,45 @@ typedef __pthread_alloc __single_client_alloc; typedef __pthread_alloc __multithreaded_alloc; -# else +#else /* _STLP_USE_PERTHREAD_ALLOC */ -# if defined ( _STLP_USE_NEWALLOC ) +# if defined (_STLP_USE_NEWALLOC) -# if defined ( _STLP_DEBUG_ALLOC ) +# if defined (_STLP_DEBUG_ALLOC) typedef __debug_alloc<__new_alloc> __sgi_alloc; -# else +# else typedef __new_alloc __sgi_alloc; -# endif /* _STLP_DEBUG_ALLOC */ +# endif /* _STLP_DEBUG_ALLOC */ typedef __new_alloc __single_client_alloc; typedef __new_alloc __multithreaded_alloc; # elif defined (_STLP_USE_MALLOC) -# if defined ( _STLP_DEBUG_ALLOC ) -typedef __debug_alloc<__malloc_alloc<0> > __sgi_alloc; -# else -typedef __malloc_alloc<0> __sgi_alloc; -# endif /* _STLP_DEBUG_ALLOC */ +# if defined (_STLP_DEBUG_ALLOC) +typedef __debug_alloc<__malloc_alloc> __sgi_alloc; +# else +typedef __malloc_alloc __sgi_alloc; +# endif /* _STLP_DEBUG_ALLOC */ -typedef __malloc_alloc<0> __single_client_alloc; -typedef __malloc_alloc<0> __multithreaded_alloc; +typedef __malloc_alloc __single_client_alloc; +typedef __malloc_alloc __multithreaded_alloc; -# else +# else -# if defined ( _STLP_DEBUG_ALLOC ) -typedef __debug_alloc<_Node_alloc> __sgi_alloc; -# else -typedef _Node_alloc __sgi_alloc; -# endif +# if defined (_STLP_DEBUG_ALLOC) +typedef __debug_alloc<__node_alloc> __sgi_alloc; +# else +typedef __node_alloc __sgi_alloc; +# endif -typedef __node_alloc __single_client_alloc; -typedef __node_alloc __multithreaded_alloc; +typedef __node_alloc __single_client_alloc; +typedef __node_alloc __multithreaded_alloc; # endif /* _STLP_USE_NEWALLOC */ -# endif /* PTHREAD_ALLOC */ +#endif /* _STLP_USE_PERTHREAD_ALLOC */ -// This implements allocators as specified in the C++ standard. +// This implements allocators as specified in the C++ standard. // // Note that standard-conforming allocators use many language features // that are not yet widely implemented. In particular, they rely on @@ -338,48 +321,127 @@ // templates, the typename keyword, and the use of the template keyword // to refer to a template member of a dependent type. +/* template -class allocator { +struct _AllocatorAux { + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + + pointer address(reference __x) const {return &__x;} + const_pointer address(const_reference __x) const { return &__x; } +}; + +template +struct _AllocatorAux { + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + + const_pointer address(const_reference __x) const { return &__x; } +}; +*/ + +template +class allocator //: public _AllocatorAux<_Tp> +/* A small helper struct to recognize STLport allocator implementation + * from any user specialization one. + */ + : public __stlport_class > { public: - typedef _Tp value_type; - typedef value_type * pointer; + typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) +#if defined (_STLP_MEMBER_TEMPLATE_CLASSES) template struct rebind { typedef allocator<_Tp1> other; }; -# endif +#endif allocator() _STLP_NOTHROW {} - # if defined (_STLP_MEMBER_TEMPLATES) +#if defined (_STLP_MEMBER_TEMPLATES) template allocator(const allocator<_Tp1>&) _STLP_NOTHROW {} - # endif +#endif allocator(const allocator<_Tp>&) _STLP_NOTHROW {} + allocator(__move_source > /*src*/) _STLP_NOTHROW {} ~allocator() _STLP_NOTHROW {} - pointer address(reference __x) const { return &__x; } + pointer address(reference __x) const {return &__x;} const_pointer address(const_reference __x) const { return &__x; } // __n is permitted to be 0. The C++ standard says nothing about what the return value is when __n == 0. - _Tp* allocate(size_type __n, const void* = 0) { - return __n != 0 ? __REINTERPRET_CAST(value_type*,__sgi_alloc::allocate(__n * sizeof(value_type))) : 0; + _Tp* allocate(size_type __n, const void* = 0) { + if (__n > max_size()) { + __THROW_BAD_ALLOC; + } + if (__n != 0) { + size_type __buf_size = __n * sizeof(value_type); + _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size)); +#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC) + if (__ret != 0) { + memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size); + } +#endif + return __ret; + } + else + return 0; } // __p is permitted to be a null pointer, only if n==0. void deallocate(pointer __p, size_type __n) { _STLP_ASSERT( (__p == 0) == (__n == 0) ) - if (__p != 0) __sgi_alloc::deallocate((void*)__p, __n * sizeof(value_type)); + if (__p != 0) { +#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC) + memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type)); +#endif + __sgi_alloc::deallocate((void*)__p, __n * sizeof(value_type)); + } } // backwards compatibility void deallocate(pointer __p) const { if (__p != 0) __sgi_alloc::deallocate((void*)__p, sizeof(value_type)); } size_type max_size() const _STLP_NOTHROW { return size_t(-1) / sizeof(value_type); } - void construct(pointer __p, const _Tp& __val) { _STLP_STD::_Construct(__p, __val); } + void construct(pointer __p, const_reference __val) { _STLP_STD::_Copy_Construct(__p, __val); } void destroy(pointer __p) { _STLP_STD::_Destroy(__p); } -# if defined(__MRC__)||(defined(__SC__) && !defined(__DMC__)) - template bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; } +#if defined(__MRC__)||(defined(__SC__) && !defined(__DMC__)) + template bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; } template bool operator!=(const allocator<_T2>&) const _STLP_NOTHROW { return false; } -# endif +#endif + +#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) + //This is just to make swap workaround for compiler without template function partial + //happy. + void swap(allocator<_Tp>&) {} +#endif + +#if defined (_STLP_NO_EXTENSIONS) + /* STLport extension giving rounded size of an allocated memory buffer + * This method do not have to be part of a user defined allocator implementation + * and won't even be called if such a function was granted. + */ +protected: +#endif + _Tp* allocate(size_type __n, size_type& __allocated_n) { + if (__n > max_size()) { + __THROW_BAD_ALLOC; + } + + if (__n != 0) { + size_type __buf_size = __n * sizeof(value_type); + _Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size)); +#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC) + if (__ret != 0) { + memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size); + } +#endif + __allocated_n = __buf_size / sizeof(value_type); + return __ret; + } + else + return 0; + } }; _STLP_TEMPLATE_NULL @@ -389,83 +451,89 @@ typedef ptrdiff_t difference_type; typedef void* pointer; typedef const void* const_pointer; -# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) +#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) typedef void value_type; -# endif -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) +#endif +#if defined (_STLP_MEMBER_TEMPLATE_CLASSES) template struct rebind { typedef allocator<_Tp1> other; }; -# endif -# if defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__)) //*ty 03/24/2001 - MPW compilers get confused on these operator definitions +#endif +#if defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__)) //*ty 03/24/2001 - MPW compilers get confused on these operator definitions template bool operator==(const allocator<_T2>&) const _STLP_NOTHROW { return true; } template bool operator!=(const allocator<_T2>&) const _STLP_NOTHROW { return false; } -# endif +#endif }; -#if !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__))) //*ty 03/24/2001 - MPW compilers get confused on these operator definitions +#if !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__))) //*ty 03/24/2001 - MPW compilers get confused on these operator definitions template inline bool _STLP_CALL operator==(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW { return true; } template inline bool _STLP_CALL operator!=(const allocator<_T1>&, const allocator<_T2>&) _STLP_NOTHROW { return false; } #endif -# if defined (_STLP_USE_TEMPLATE_EXPORT) +#if defined (_STLP_USE_TEMPLATE_EXPORT) _STLP_EXPORT_TEMPLATE_CLASS allocator; # if defined (_STLP_HAS_WCHAR_T) _STLP_EXPORT_TEMPLATE_CLASS allocator; # endif -# endif /* _STLP_USE_TEMPLATE_EXPORT */ +# if defined (_STLP_USE_PTR_SPECIALIZATIONS) +_STLP_EXPORT_TEMPLATE_CLASS allocator; +# endif +#endif -// Another allocator adaptor: _Alloc_traits. This serves two -// purposes. First, make it possible to write containers that can use -// either SGI-style allocators or standard-conforming allocator. +_STLP_MOVE_TO_PRIV_NAMESPACE -// The fully general version. -template -struct _Alloc_traits -{ - typedef _Allocator _Orig; -# if defined (_STLP_USE_NESTED_TCLASS_THROUGHT_TPARAM) - typedef typename _Allocator::_STLP_TEMPLATE rebind<_Tp> _Rebind_type; - typedef typename _Rebind_type::other allocator_type; - static allocator_type create_allocator(const _Orig& __a) { return allocator_type(__a); } -# else - // this is not actually true, used only to pass this type through - // to dynamic overload selection in _STLP_alloc_proxy methods - typedef _Allocator allocator_type; -# endif /* _STLP_USE_NESTED_TCLASS_THROUGHT_TPARAM */ +template +struct __alloc_type_traits { +#if !defined (__BORLANDC__) + typedef typename _IsSTLportClass >::_Ret _STLportAlloc; +#else + enum { _Is = _IsSTLportClass >::_Is }; + typedef typename __bool2type<_Is>::_Ret _STLportAlloc; +#endif + //The default allocator implementation which is recognize thanks to the + //__stlport_class inheritance is a stateless object so: + typedef _STLportAlloc has_trivial_default_constructor; + typedef _STLportAlloc has_trivial_copy_constructor; + typedef _STLportAlloc has_trivial_assignment_operator; + typedef _STLportAlloc has_trivial_destructor; + typedef _STLportAlloc is_POD_type; }; -#ifndef _STLP_FORCE_ALLOCATORS -#define _STLP_FORCE_ALLOCATORS(a,y) +_STLP_MOVE_TO_STD_NAMESPACE + +#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) +template +struct __type_traits > : _STLP_PRIV __alloc_type_traits<_Tp> {}; +#else +_STLP_TEMPLATE_NULL +struct __type_traits > : _STLP_PRIV __alloc_type_traits {}; +# if defined (_STLP_HAS_WCHAR_T) +_STLP_TEMPLATE_NULL +struct __type_traits > : _STLP_PRIV __alloc_type_traits {}; +# endif +# if defined (_STLP_USE_PTR_SPECIALIZATIONS) +_STLP_TEMPLATE_NULL +struct __type_traits > : _STLP_PRIV __alloc_type_traits {}; +# endif #endif -#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && ! defined (_STLP_MEMBER_TEMPLATE_CLASSES) + +#if !defined (_STLP_FORCE_ALLOCATORS) +# define _STLP_FORCE_ALLOCATORS(a,y) +#endif + +#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_MEMBER_TEMPLATE_CLASSES) // The version for the default allocator, for rare occasion when we have partial spec w/o member template classes template struct _Alloc_traits<_Tp, allocator<_Tp1> > { typedef allocator<_Tp1> _Orig; typedef allocator<_Tp> allocator_type; - static allocator_type create_allocator(const allocator<_Tp1 >& __a) { return allocator_type(__a); } + static allocator_type create_allocator(const allocator<_Tp1 >& __a) + { return allocator_type(_STLP_CONVERT_ALLOCATOR(__a, _Tp)); } }; #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ -/* macro to convert the allocator for initialization - * not using MEMBER_TEMPLATE_CLASSES as it should work given template constructor */ -#if defined (_STLP_MEMBER_TEMPLATES) || ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) -/* if _STLP_NO_TEMPLATE_CONVERSIONS is set, the member template constructor is - * not used implicitly to convert allocator parameter, so let us do it explicitly */ -# if defined (_STLP_MEMBER_TEMPLATE_CLASSES) && defined (_STLP_NO_TEMPLATE_CONVERSIONS) -# define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0) -# else -# define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __a -# endif -/* else convert, but only if partial specialization works, since else - * Container::allocator_type won't be different */ -#else -# define _STLP_CONVERT_ALLOCATOR(__a, _Tp) __stl_alloc_create(__a,(_Tp*)0) -#endif - -# if defined (_STLP_USE_NESTED_TCLASS_THROUGHT_TPARAM) +#if !defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) && defined (_STLP_MEMBER_TEMPLATES) template inline _STLP_TYPENAME_ON_RETURN_TYPE _Alloc_traits<_Tp, _Alloc>::allocator_type _STLP_CALL __stl_alloc_create(const _Alloc& __a, const _Tp*) { @@ -481,59 +549,114 @@ template inline allocator<_Tp2> _STLP_CALL __stl_alloc_create(const allocator<_Tp1>&, const _Tp2*) { return allocator<_Tp2>(); } -#endif /* _STLP_USE_NESTED_TCLASS_THROUGHT_TPARAM */ +#endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */ -# ifdef _STLP_USE_RAW_SGI_ALLOCATORS +#if defined (_STLP_USE_RAW_SGI_ALLOCATORS) // move obsolete stuff out of the way -# include -# endif +# include +#endif + +_STLP_MOVE_TO_PRIV_NAMESPACE // inheritance is being used for EBO optimization template class _STLP_alloc_proxy : public _MaybeReboundAlloc { private: typedef _MaybeReboundAlloc _Base; + typedef typename _Base::size_type size_type; typedef _STLP_alloc_proxy<_Value, _Tp, _MaybeReboundAlloc> _Self; public: _Value _M_data; - inline _STLP_alloc_proxy(const _MaybeReboundAlloc& __a, _Value __p) : _MaybeReboundAlloc(__a), _M_data(__p) {} -# if 0 - inline _STLP_alloc_proxy(const _Self& __x) : _MaybeReboundAlloc(__x), _M_data(__x._M_data) {} - // construction/destruction - inline _Self& operator = (const _Self& __x) { - *(_MaybeReboundAlloc*)this = *(_MaybeReboundAlloc*)__x; - _M_data = __x._M_data; return *this; - } - inline _Self& operator = (const _Base& __x) { ((_Base&)*this) = __x; return *this; } -# endif + _STLP_alloc_proxy (const _MaybeReboundAlloc& __a, _Value __p) : + _MaybeReboundAlloc(__a), _M_data(__p) {} + + _STLP_alloc_proxy (__move_source<_Self> src) : + _MaybeReboundAlloc(_STLP_PRIV _AsMoveSource<_Base>(src.get())), + _M_data(_STLP_PRIV _AsMoveSource<_Value>(src.get()._M_data)) {} + +private: + /* Following are helper methods to detect stateless allocators and avoid + * swap in this case. For some compilers (VC6) it is a workaround for a + * compiler bug in the Empty Base class Optimization feature, for others + * it is a small optimization or nothing if no EBO. */ + void _M_swap_alloc(_Self&, const __true_type& /*_IsStateless*/) + {} + + void _M_swap_alloc(_Self& __x, const __false_type& /*_IsStateless*/) { + _MaybeReboundAlloc &__base_this = *this; + _MaybeReboundAlloc &__base_x = __x; + _STLP_STD::swap(__base_this, __base_x); + } + +public: + void _M_swap_alloc(_Self& __x) { +#if !defined (__BORLANDC__) + typedef typename _IsStateless<_MaybeReboundAlloc>::_Ret _StatelessAlloc; +#else + typedef typename __bool2type<_IsStateless<_MaybeReboundAlloc>::_Is>::_Ret _StatelessAlloc; +#endif + _M_swap_alloc(__x, _StatelessAlloc()); + } + + /* We need to define the following swap implementation for allocator with state + * as those allocators might have implement a special swap function to correctly + * move datas from an instance to the oher, _STLP_alloc_proxy should not break + * this mecanism. */ + void swap(_Self& __x) { + _M_swap_alloc(__x); + _STLP_STD::swap(_M_data, __x._M_data); + } + + _Tp* allocate(size_type __n, size_type& __allocated_n) { +#if !defined (__BORLANDC__) + typedef typename _IsSTLportClass<_MaybeReboundAlloc>::_Ret _STLportAlloc; +#else + typedef typename __bool2type<_IsSTLportClass<_MaybeReboundAlloc>::_Is>::_Ret _STLportAlloc; +#endif + return allocate(__n, __allocated_n, _STLportAlloc()); + } + // Unified interface to perform allocate()/deallocate() with limited // language support -#if ! defined (_STLP_USE_NESTED_TCLASS_THROUGHT_TPARAM) +#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) // else it is rebound already, and allocate() member is accessible - inline _Tp* allocate(size_t __n) { - return __stl_alloc_rebind(__STATIC_CAST(_Base&,*this),(_Tp*)0).allocate(__n,0); - } - inline void deallocate(_Tp* __p, size_t __n) { - __stl_alloc_rebind(__STATIC_CAST(_Base&, *this),(_Tp*)0).deallocate(__p, __n); - } -#endif /* !_STLP_USE_NESTED_TCLASS_THROUGHT_TPARAM */ + _Tp* allocate(size_type __n) + { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, 0); } + void deallocate(_Tp* __p, size_type __n) + { __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).deallocate(__p, __n); } +private: + _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/) + { return __stl_alloc_rebind(__STATIC_CAST(_Base&, *this), __STATIC_CAST(_Tp*, 0)).allocate(__n, __allocated_n); } +#else + //Expose Standard allocate overload (using expression do not work for some compilers (Borland)) + _Tp* allocate(size_type __n) + { return _Base::allocate(__n); } +private: + _Tp* allocate(size_type __n, size_type& __allocated_n, const __true_type& /*STLport allocator*/) + { return _Base::allocate(__n, __allocated_n); } +#endif + + _Tp* allocate(size_type __n, size_type& __allocated_n, const __false_type& /*STLport allocator*/) + { __allocated_n = __n; return allocate(__n); } }; -# if defined (_STLP_USE_TEMPLATE_EXPORT) -_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy >; +#if defined (_STLP_USE_TEMPLATE_EXPORT) +_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy >; # if defined (_STLP_HAS_WCHAR_T) -_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy >; +_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy >; # endif -# endif /* _STLP_USE_TEMPLATE_EXPORT */ +# if defined (_STLP_USE_PTR_SPECIALIZATIONS) +_STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy >; +# endif +#endif -# undef _STLP_NODE_ALLOCATOR_THREADS - +_STLP_MOVE_TO_STD_NAMESPACE _STLP_END_NAMESPACE -# if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION) +#if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION) # include -# endif +#endif #endif /* _STLP_INTERNAL_ALLOC_H */