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)
53
(void)p; // warning suppression
59
#if !defined(BOOST_NO_STD_ALLOCATOR)
63
#define BOOST_DEFAULT_ALLOCATOR(T) std::allocator< T >
65
namespace boost{ namespace detail{
67
template <class T, class A>
68
struct rebind_allocator
70
typedef typename A::template rebind<T> binder;
71
typedef typename binder::other type;
77
#elif !defined(BOOST_NO_MEMBER_TEMPLATES)
79
// no std::allocator, but the compiler supports the necessary syntax,
80
// write our own allocator instead:
82
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator< T >
84
namespace boost{ namespace detail{
92
typedef value_type * pointer;
93
typedef const T* const_pointer;
95
typedef const T& const_reference;
96
typedef std::size_t size_type;
97
typedef std::ptrdiff_t difference_type;
102
typedef allocator<U> other;
108
allocator(const allocator<U>&){}
110
allocator(const allocator&){}
113
allocator& operator=(const allocator<U>&)
118
pointer address(reference x) { return &x; }
120
const_pointer address(const_reference x) const { return &x; }
122
pointer allocate(size_type n, const void* = 0)
124
#ifdef BOOST_HAVE_SGI_ALLOCATOR
126
reinterpret_cast<pointer>(alloc_type::allocate(n * sizeof(value_type)))
130
reinterpret_cast<pointer>(::operator new(n * sizeof(value_type)))
135
void deallocate(pointer p, size_type n)
137
#ifdef BOOST_HAVE_SGI_ALLOCATOR
138
assert( (p == 0) == (n == 0) );
140
alloc_type::deallocate((void*)p, n);
142
assert( (p == 0) == (n == 0) );
144
::operator delete((void*)p);
148
size_type max_size() const
149
{ return size_t(-1) / sizeof(value_type); }
151
void construct(pointer p, const T& val) const
152
{ allocator_construct(p, val); }
154
void destroy(pointer p) const
155
{ allocator_destroy(p); }
158
template <class T, class A>
159
struct rebind_allocator
161
typedef typename A::template rebind<T> binder;
162
typedef typename binder::other type;
165
} // namespace detail
170
// no std::allocator, use workaround version instead,
171
// each allocator class must derive from a base class
172
// that allocates blocks of bytes:
174
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter<T, ::boost::detail::simple_alloc>
176
namespace boost{ namespace detail{
182
typedef void value_type;
183
typedef value_type * pointer;
184
typedef const void* const_pointer;
185
typedef std::size_t size_type;
186
typedef std::ptrdiff_t difference_type;
189
simple_alloc(const simple_alloc&){}
193
pointer allocate(size_type n, const void* = 0)
195
#ifdef BOOST_HAVE_SGI_ALLOCATOR
197
reinterpret_cast<pointer>(alloc_type::allocate(n))
201
reinterpret_cast<pointer>(::operator new(n))
206
void deallocate(pointer p, size_type n)
208
#ifdef BOOST_HAVE_SGI_ALLOCATOR
209
assert( (p == 0) == (n == 0) );
211
alloc_type::deallocate((void*)p, n);
213
assert( (p == 0) == (n == 0) );
215
::operator delete((void*)p);
220
template <class T, class Base>
221
class allocator_adapter : public Base
225
typedef T value_type;
226
typedef value_type * pointer;
227
typedef const T* const_pointer;
228
typedef T& reference;
229
typedef const T& const_reference;
230
typedef size_t size_type;
231
typedef std::ptrdiff_t difference_type;
232
typedef Base base_type;
234
allocator_adapter(){}
235
allocator_adapter(const base_type& x) : Base(x){}
236
allocator_adapter& operator=(const base_type& x)
238
*(static_cast<base_type*>(this)) = x;
242
~allocator_adapter(){}
244
pointer address(reference x) { return &x; }
246
const_pointer address(const_reference x) const { return &x; }
248
pointer allocate(size_type n, const void* = 0)
251
reinterpret_cast<pointer>(base_type::allocate(n * sizeof(value_type)))
255
void deallocate(pointer p, size_type n)
257
assert( (p == 0) == (n == 0) );
259
static_cast<base_type*>(this)->deallocate((void*)p, n * sizeof(value_type));
262
size_type max_size() const
263
{ return size_t(-1) / sizeof(value_type); }
265
void construct(pointer p, const T& val) const
266
{ allocator_construct(p, val); }
268
void destroy(pointer p) const
269
{ allocator_destroy(p); }
272
template <class T, class A>
273
struct rebind_allocator
275
typedef allocator_adapter<T, typename A::base_type> type;
278
} // namespace detail
283
#endif // include guard