6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Dr John Maddock makes no representations
11 * about the suitability of this software for any purpose.
12 * It is provided "as is" without express or implied warranty.
16 #ifndef BOOST_DETAIL_ALLOCATOR_HPP
17 #define BOOST_DETAIL_ALLOCATOR_HPP
19 #include <boost/config.hpp>
21 #if defined(BOOST_NO_STDC_NAMESPACE)
28 // see if we have SGI alloc class:
29 #if defined(BOOST_NO_STD_ALLOCATOR) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) || defined(__GLIBCPP__) || defined(__STL_CONFIG_H))
30 # define BOOST_HAVE_SGI_ALLOCATOR
32 # if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
33 namespace boost{ namespace detail{
34 typedef std::__sgi_alloc alloc_type;
37 namespace boost{ namespace detail{
38 typedef std::alloc alloc_type;
44 namespace boost{ namespace detail{
47 void allocator_construct(T* p, const T& t)
51 void allocator_destroy(T* p)
56 #if !defined(BOOST_NO_STD_ALLOCATOR)
60 #define BOOST_DEFAULT_ALLOCATOR(T) std::allocator<T>
62 namespace boost{ namespace detail{
64 template <class T, class A>
65 struct rebind_allocator
67 typedef typename A::template rebind<T> binder;
68 typedef typename binder::other type;
74 #elif !defined(BOOST_NO_MEMBER_TEMPLATES)
76 // no std::allocator, but the compiler supports the necessary syntax,
77 // write our own allocator instead:
79 #define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator<T>
81 namespace boost{ namespace detail{
89 typedef value_type * pointer;
90 typedef const T* const_pointer;
92 typedef const T& const_reference;
93 typedef std::size_t size_type;
94 typedef std::ptrdiff_t difference_type;
99 typedef allocator<U> other;
105 allocator(const allocator<U>&){}
107 allocator(const allocator&){}
110 allocator& operator=(const allocator<U>&)
115 pointer address(reference x) { return &x; }
117 const_pointer address(const_reference x) const { return &x; }
119 pointer allocate(size_type n, const void* = 0)
121 #ifdef BOOST_HAVE_SGI_ALLOCATOR
123 reinterpret_cast<pointer>(alloc_type::allocate(n * sizeof(value_type)))
127 reinterpret_cast<pointer>(::operator new(n * sizeof(value_type)))
132 void deallocate(pointer p, size_type n)
134 #ifdef BOOST_HAVE_SGI_ALLOCATOR
135 assert( (p == 0) == (n == 0) );
137 alloc_type::deallocate((void*)p, n);
139 assert( (p == 0) == (n == 0) );
141 ::operator delete((void*)p);
145 size_type max_size() const
146 { return size_t(-1) / sizeof(value_type); }
148 void construct(pointer p, const T& val) const
149 { allocator_construct(p, val); }
151 void destroy(pointer p) const
152 { allocator_destroy(p); }
155 template <class T, class A>
156 struct rebind_allocator
158 typedef typename A::template rebind<T> binder;
159 typedef typename binder::other type;
162 } // namespace detail
167 // no std::allocator, use workaround version instead,
168 // each allocator class must derive from a base class
169 // that allocates blocks of bytes:
171 #define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter<T, ::boost::detail::simple_alloc>
173 namespace boost{ namespace detail{
179 typedef void value_type;
180 typedef value_type * pointer;
181 typedef const void* const_pointer;
182 typedef std::size_t size_type;
183 typedef std::ptrdiff_t difference_type;
186 simple_alloc(const simple_alloc&){}
190 pointer allocate(size_type n, const void* = 0)
192 #ifdef BOOST_HAVE_SGI_ALLOCATOR
194 reinterpret_cast<pointer>(alloc_type::allocate(n))
198 reinterpret_cast<pointer>(::operator new(n))
203 void deallocate(pointer p, size_type n)
205 #ifdef BOOST_HAVE_SGI_ALLOCATOR
206 assert( (p == 0) == (n == 0) );
208 alloc_type::deallocate((void*)p, n);
210 assert( (p == 0) == (n == 0) );
212 ::operator delete((void*)p);
217 template <class T, class Base>
218 class allocator_adapter : public Base
222 typedef T value_type;
223 typedef value_type * pointer;
224 typedef const T* const_pointer;
225 typedef T& reference;
226 typedef const T& const_reference;
227 typedef size_t size_type;
228 typedef std::ptrdiff_t difference_type;
229 typedef Base base_type;
231 allocator_adapter(){}
232 allocator_adapter(const base_type& x) : Base(x){}
233 allocator_adapter& operator=(const base_type& x)
235 *(static_cast<base_type*>(this)) = x;
239 ~allocator_adapter(){}
241 pointer address(reference x) { return &x; }
243 const_pointer address(const_reference x) const { return &x; }
245 pointer allocate(size_type n, const void* = 0)
248 reinterpret_cast<pointer>(base_type::allocate(n * sizeof(value_type)))
252 void deallocate(pointer p, size_type n)
254 assert( (p == 0) == (n == 0) );
256 static_cast<base_type*>(this)->deallocate((void*)p, n * sizeof(value_type));
259 size_type max_size() const
260 { return size_t(-1) / sizeof(value_type); }
262 void construct(pointer p, const T& val) const
263 { allocator_construct(p, val); }
265 void destroy(pointer p) const
266 { allocator_destroy(p); }
269 template <class T, class A>
270 struct rebind_allocator
272 typedef allocator_adapter<T, typename A::base_type> type;
275 } // namespace detail
280 #endif // include guard