📄 allocator.hpp
字号:
/* * * Copyright (c) 2001 * Dr 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 <boost/config.hpp>#include <cstdlib>#include <new>#include <assert.h>#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 <memory># if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)namespace boost{ namespace detail{ typedef std::__sgi_alloc alloc_type;}}# elsenamespace boost{ namespace detail{ typedef std::alloc alloc_type;}}# endif#endifnamespace boost{ namespace detail{template <class T>void allocator_construct(T* p, const T& t){ new (p) T(t); }template <class T>void allocator_destroy(T* p){ (void)p; // warning suppression p->~T(); }} }#if !defined(BOOST_NO_STD_ALLOCATOR)#include <memory>#define BOOST_DEFAULT_ALLOCATOR(T) std::allocator< T >namespace boost{ namespace detail{template <class T, class A>struct rebind_allocator{ typedef typename A::template rebind<T> 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 T>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 <class U> struct rebind { typedef allocator<U> other; }; allocator(){} template <class U> allocator(const allocator<U>&){} allocator(const allocator&){} template <class U> allocator& operator=(const allocator<U>&) { 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<pointer>(alloc_type::allocate(n * sizeof(value_type))) : 0; #else return n != 0 ? reinterpret_cast<pointer>(::operator new(n * sizeof(value_type))) : 0; #endif } void deallocate(pointer p, size_type n) { #ifdef BOOST_HAVE_SGI_ALLOCATOR assert( (p == 0) == (n == 0) ); if (p != 0) alloc_type::deallocate((void*)p, n); #else 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 <class T, class A>struct rebind_allocator{ typedef typename A::template rebind<T> 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<T, ::boost::detail::simple_alloc>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<pointer>(alloc_type::allocate(n)) : 0; #else return n != 0 ? reinterpret_cast<pointer>(::operator new(n)) : 0; #endif } void deallocate(pointer p, size_type n) { #ifdef BOOST_HAVE_SGI_ALLOCATOR assert( (p == 0) == (n == 0) ); if (p != 0) alloc_type::deallocate((void*)p, n); #else assert( (p == 0) == (n == 0) ); if (p != 0) ::operator delete((void*)p); #endif }};template <class T, class Base>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<base_type*>(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<pointer>(base_type::allocate(n * sizeof(value_type))) : 0; } void deallocate(pointer p, size_type n) { assert( (p == 0) == (n == 0) ); if (p != 0) static_cast<base_type*>(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 <class T, class A>struct rebind_allocator{ typedef allocator_adapter<T, typename A::base_type> type;};} // namespace detail} // namespace boost#endif#endif // include guard
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -