]> git.lyx.org Git - lyx.git/blob - boost/boost/detail/allocator.hpp
major boost update
[lyx.git] / boost / boost / detail / allocator.hpp
1 /*
2  *
3  * Copyright (c) 2001
4  * Dr John Maddock
5  *
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.
13  *
14  */
15
16 #ifndef BOOST_DETAIL_ALLOCATOR_HPP
17 #define BOOST_DETAIL_ALLOCATOR_HPP
18
19 #include <boost/config.hpp>
20 #include <cstdlib>
21 #if defined(BOOST_NO_STDC_NAMESPACE)
22 namespace std{
23 using ::ptrdiff_t;
24 using ::size_t;
25 }
26 #endif
27
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
31 #  include <memory>
32 #  if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
33 namespace boost{ namespace detail{
34    typedef std::__sgi_alloc alloc_type;
35 }}
36 #  else
37 namespace boost{ namespace detail{
38    typedef std::alloc alloc_type;
39 }}
40 #  endif
41 #endif
42
43
44 namespace boost{ namespace detail{
45
46 template <class T>
47 void allocator_construct(T* p, const T& t)
48 { new (p) T(t); }
49
50 template <class T>
51 void allocator_destroy(T* p)
52 { p->~T(); }
53
54 } }
55
56 #if !defined(BOOST_NO_STD_ALLOCATOR)
57
58 #include <memory>
59
60 #define BOOST_DEFAULT_ALLOCATOR(T) std::allocator<T>
61
62 namespace boost{ namespace detail{
63
64 template <class T, class A>
65 struct rebind_allocator
66 {
67    typedef typename A::template rebind<T> binder;
68    typedef typename binder::other type;
69 };
70
71 } // namespace detail
72 } // namespace boost
73
74 #elif !defined(BOOST_NO_MEMBER_TEMPLATES)
75
76 // no std::allocator, but the compiler supports the necessary syntax,
77 // write our own allocator instead:
78
79 #define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator<T>
80
81 namespace boost{ namespace detail{
82
83 template <class T>
84 class allocator
85 {
86 public:
87
88    typedef T              value_type;
89    typedef value_type *   pointer;
90    typedef const T*       const_pointer;
91    typedef T&             reference;
92    typedef const T&       const_reference;
93    typedef std::size_t    size_type;
94    typedef std::ptrdiff_t difference_type;
95
96    template <class U>
97    struct rebind
98    {
99       typedef allocator<U> other;
100    };
101
102    allocator(){}
103    
104    template <class U>
105    allocator(const allocator<U>&){}
106
107    allocator(const allocator&){}
108
109    template <class U>
110    allocator& operator=(const allocator<U>&)
111    { return *this; }
112
113    ~allocator(){}
114
115    pointer address(reference x) { return &x; }
116
117    const_pointer address(const_reference x) const { return &x; }
118
119    pointer allocate(size_type n, const void* = 0) 
120    {
121       #ifdef BOOST_HAVE_SGI_ALLOCATOR
122       return n != 0 ?
123          reinterpret_cast<pointer>(alloc_type::allocate(n * sizeof(value_type)))
124          : 0;
125       #else
126       return n != 0 ?
127          reinterpret_cast<pointer>(::operator new(n * sizeof(value_type)))
128          : 0;
129       #endif
130    }
131
132    void deallocate(pointer p, size_type n) 
133    {
134       #ifdef BOOST_HAVE_SGI_ALLOCATOR
135       assert( (p == 0) == (n == 0) );
136       if (p != 0)
137          alloc_type::deallocate((void*)p, n);
138       #else
139       assert( (p == 0) == (n == 0) );
140       if (p != 0)
141          ::operator delete((void*)p);
142       #endif
143    }
144
145    size_type max_size() const
146    { return size_t(-1) / sizeof(value_type); }
147
148    void construct(pointer p, const T& val) const
149    { allocator_construct(p, val); }
150
151    void destroy(pointer p) const
152    { allocator_destroy(p); }
153 };
154
155 template <class T, class A>
156 struct rebind_allocator
157 {
158    typedef typename A::template rebind<T> binder;
159    typedef typename binder::other type;
160 };
161
162 } // namespace detail
163 } // namespace boost
164
165 #else
166
167 // no std::allocator, use workaround version instead,
168 // each allocator class must derive from a base class
169 // that allocates blocks of bytes:
170
171 #define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter<T, ::boost::detail::simple_alloc>
172
173 namespace boost{ namespace detail{
174
175 class simple_alloc
176 {
177 public:
178
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;
184
185    simple_alloc(){}
186    simple_alloc(const simple_alloc&){}
187
188    ~simple_alloc(){}
189
190    pointer allocate(size_type n, const void* = 0) 
191    {
192       #ifdef BOOST_HAVE_SGI_ALLOCATOR
193       return n != 0 ?
194          reinterpret_cast<pointer>(alloc_type::allocate(n))
195          : 0;
196       #else
197       return n != 0 ?
198          reinterpret_cast<pointer>(::operator new(n))
199          : 0;
200       #endif
201    }
202
203    void deallocate(pointer p, size_type n) 
204    {
205       #ifdef BOOST_HAVE_SGI_ALLOCATOR
206       assert( (p == 0) == (n == 0) );
207       if (p != 0)
208          alloc_type::deallocate((void*)p, n);
209       #else
210       assert( (p == 0) == (n == 0) );
211       if (p != 0)
212          ::operator delete((void*)p);
213       #endif
214    }
215 };
216
217 template <class T, class Base>
218 class allocator_adapter : public Base
219 {
220 public:
221
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;
230
231    allocator_adapter(){}
232    allocator_adapter(const base_type& x) : Base(x){}
233    allocator_adapter& operator=(const base_type& x)
234    {
235       *(static_cast<base_type*>(this)) = x;
236       return *this;
237    }
238
239    ~allocator_adapter(){}
240
241    pointer address(reference x) { return &x; }
242
243    const_pointer address(const_reference x) const { return &x; }
244
245    pointer allocate(size_type n, const void* = 0) 
246    {
247       return n != 0 ?
248          reinterpret_cast<pointer>(base_type::allocate(n * sizeof(value_type)))
249          : 0;
250    }
251
252    void deallocate(pointer p, size_type n) 
253    {
254       assert( (p == 0) == (n == 0) );
255       if (p != 0)
256          static_cast<base_type*>(this)->deallocate((void*)p, n * sizeof(value_type));
257    }
258
259    size_type max_size() const
260    { return size_t(-1) / sizeof(value_type); }
261
262    void construct(pointer p, const T& val) const
263    { allocator_construct(p, val); }
264
265    void destroy(pointer __p) const
266    { allocator_destroy(p); }
267 };
268
269 template <class T, class A>
270 struct rebind_allocator
271 {
272    typedef allocator_adapter<T, typename A::base_type> type;
273 };
274
275 } // namespace detail
276 } // namespace boost
277
278 #endif
279
280 #endif // include guard