/* * * Copyright (c) 2001 * John Maddock * * Use, modification and distribution are subject to the * Boost Software License, Version 1.0. (See accompanying file * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef BOOST_DETAIL_ALLOCATOR_HPP #define BOOST_DETAIL_ALLOCATOR_HPP #include #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::ptrdiff_t; using ::size_t; } #endif // see if we have SGI alloc class: #if defined(BOOST_NO_STD_ALLOCATOR) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) || defined(__GLIBCPP__) || defined(__STL_CONFIG_H)) # define BOOST_HAVE_SGI_ALLOCATOR # include # if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) namespace boost{ namespace detail{ typedef std::__sgi_alloc alloc_type; }} # else namespace boost{ namespace detail{ typedef std::alloc alloc_type; }} # endif #endif namespace boost{ namespace detail{ template void allocator_construct(T* p, const T& t) { new (p) T(t); } template void allocator_destroy(T* p) { (void)p; // warning suppression p->~T(); } } } #if !defined(BOOST_NO_STD_ALLOCATOR) #include #define BOOST_DEFAULT_ALLOCATOR(T) std::allocator< T > namespace boost{ namespace detail{ template struct rebind_allocator { typedef typename A::template rebind binder; typedef typename binder::other type; }; } // namespace detail } // namespace boost #elif !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__SUNPRO_CC) // no std::allocator, but the compiler supports the necessary syntax, // write our own allocator instead: #define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator< T > namespace boost{ namespace detail{ template class allocator { public: typedef T value_type; typedef value_type * pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; template struct rebind { typedef allocator other; }; allocator(){} template allocator(const allocator&){} allocator(const allocator&){} template allocator& operator=(const allocator&) { return *this; } ~allocator(){} pointer address(reference x) { return &x; } const_pointer address(const_reference x) const { return &x; } pointer allocate(size_type n, const void* = 0) { #ifdef BOOST_HAVE_SGI_ALLOCATOR return n != 0 ? reinterpret_cast(alloc_type::allocate(n * sizeof(value_type))) : 0; #else return n != 0 ? reinterpret_cast(::operator new(n * sizeof(value_type))) : 0; #endif } void deallocate(pointer p, size_type n) { #ifdef BOOST_HAVE_SGI_ALLOCATOR BOOST_ASSERT( (p == 0) == (n == 0) ); if (p != 0) alloc_type::deallocate((void*)p, n); #else BOOST_ASSERT( (p == 0) == (n == 0) ); if (p != 0) ::operator delete((void*)p); #endif } size_type max_size() const { return size_t(-1) / sizeof(value_type); } void construct(pointer p, const T& val) const { allocator_construct(p, val); } void destroy(pointer p) const { allocator_destroy(p); } }; template struct rebind_allocator { typedef typename A::template rebind binder; typedef typename binder::other type; }; } // namespace detail } // namespace boost #else // no std::allocator, use workaround version instead, // each allocator class must derive from a base class // that allocates blocks of bytes: #define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter namespace boost{ namespace detail{ class simple_alloc { public: typedef void value_type; typedef value_type * pointer; typedef const void* const_pointer; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; simple_alloc(){} simple_alloc(const simple_alloc&){} ~simple_alloc(){} pointer allocate(size_type n, const void* = 0) { #ifdef BOOST_HAVE_SGI_ALLOCATOR return n != 0 ? reinterpret_cast(alloc_type::allocate(n)) : 0; #else return n != 0 ? reinterpret_cast(::operator new(n)) : 0; #endif } void deallocate(pointer p, size_type n) { #ifdef BOOST_HAVE_SGI_ALLOCATOR BOOST_ASSERT( (p == 0) == (n == 0) ); if (p != 0) alloc_type::deallocate((void*)p, n); #else BOOST_ASSERT( (p == 0) == (n == 0) ); if (p != 0) ::operator delete((void*)p); #endif } }; template class allocator_adapter : public Base { public: typedef T value_type; typedef value_type * pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef std::ptrdiff_t difference_type; typedef Base base_type; allocator_adapter(){} allocator_adapter(const base_type& x) : Base(x){} allocator_adapter& operator=(const base_type& x) { *(static_cast(this)) = x; return *this; } ~allocator_adapter(){} pointer address(reference x) { return &x; } const_pointer address(const_reference x) const { return &x; } pointer allocate(size_type n, const void* = 0) { return n != 0 ? reinterpret_cast(base_type::allocate(n * sizeof(value_type))) : 0; } void deallocate(pointer p, size_type n) { BOOST_ASSERT( (p == 0) == (n == 0) ); if (p != 0) static_cast(this)->deallocate((void*)p, n * sizeof(value_type)); } size_type max_size() const { return size_t(-1) / sizeof(value_type); } void construct(pointer p, const T& val) const { allocator_construct(p, val); } void destroy(pointer p) const { allocator_destroy(p); } }; template struct rebind_allocator { typedef allocator_adapter type; }; } // namespace detail } // namespace boost #endif #endif // include guard