~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/detail/allocator.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
53
   (void)p; // warning suppression
 
54
   p->~T(); 
 
55
}
 
56
 
 
57
} }
 
58
 
 
59
#if !defined(BOOST_NO_STD_ALLOCATOR)
 
60
 
 
61
#include <memory>
 
62
 
 
63
#define BOOST_DEFAULT_ALLOCATOR(T) std::allocator< T >
 
64
 
 
65
namespace boost{ namespace detail{
 
66
 
 
67
template <class T, class A>
 
68
struct rebind_allocator
 
69
{
 
70
   typedef typename A::template rebind<T> binder;
 
71
   typedef typename binder::other type;
 
72
};
 
73
 
 
74
} // namespace detail
 
75
} // namespace boost
 
76
 
 
77
#elif !defined(BOOST_NO_MEMBER_TEMPLATES)
 
78
 
 
79
// no std::allocator, but the compiler supports the necessary syntax,
 
80
// write our own allocator instead:
 
81
 
 
82
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator< T >
 
83
 
 
84
namespace boost{ namespace detail{
 
85
 
 
86
template <class T>
 
87
class allocator
 
88
{
 
89
public:
 
90
 
 
91
   typedef T              value_type;
 
92
   typedef value_type *   pointer;
 
93
   typedef const T*       const_pointer;
 
94
   typedef T&             reference;
 
95
   typedef const T&       const_reference;
 
96
   typedef std::size_t    size_type;
 
97
   typedef std::ptrdiff_t difference_type;
 
98
 
 
99
   template <class U>
 
100
   struct rebind
 
101
   {
 
102
      typedef allocator<U> other;
 
103
   };
 
104
 
 
105
   allocator(){}
 
106
   
 
107
   template <class U>
 
108
   allocator(const allocator<U>&){}
 
109
 
 
110
   allocator(const allocator&){}
 
111
 
 
112
   template <class U>
 
113
   allocator& operator=(const allocator<U>&)
 
114
   { return *this; }
 
115
 
 
116
   ~allocator(){}
 
117
 
 
118
   pointer address(reference x) { return &x; }
 
119
 
 
120
   const_pointer address(const_reference x) const { return &x; }
 
121
 
 
122
   pointer allocate(size_type n, const void* = 0) 
 
123
   {
 
124
      #ifdef BOOST_HAVE_SGI_ALLOCATOR
 
125
      return n != 0 ?
 
126
         reinterpret_cast<pointer>(alloc_type::allocate(n * sizeof(value_type)))
 
127
         : 0;
 
128
      #else
 
129
      return n != 0 ?
 
130
         reinterpret_cast<pointer>(::operator new(n * sizeof(value_type)))
 
131
         : 0;
 
132
      #endif
 
133
   }
 
134
 
 
135
   void deallocate(pointer p, size_type n) 
 
136
   {
 
137
      #ifdef BOOST_HAVE_SGI_ALLOCATOR
 
138
      assert( (p == 0) == (n == 0) );
 
139
      if (p != 0)
 
140
         alloc_type::deallocate((void*)p, n);
 
141
      #else
 
142
      assert( (p == 0) == (n == 0) );
 
143
      if (p != 0)
 
144
         ::operator delete((void*)p);
 
145
      #endif
 
146
   }
 
147
 
 
148
   size_type max_size() const
 
149
   { return size_t(-1) / sizeof(value_type); }
 
150
 
 
151
   void construct(pointer p, const T& val) const
 
152
   { allocator_construct(p, val); }
 
153
 
 
154
   void destroy(pointer p) const
 
155
   { allocator_destroy(p); }
 
156
};
 
157
 
 
158
template <class T, class A>
 
159
struct rebind_allocator
 
160
{
 
161
   typedef typename A::template rebind<T> binder;
 
162
   typedef typename binder::other type;
 
163
};
 
164
 
 
165
} // namespace detail
 
166
} // namespace boost
 
167
 
 
168
#else
 
169
 
 
170
// no std::allocator, use workaround version instead,
 
171
// each allocator class must derive from a base class
 
172
// that allocates blocks of bytes:
 
173
 
 
174
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter<T, ::boost::detail::simple_alloc>
 
175
 
 
176
namespace boost{ namespace detail{
 
177
 
 
178
class simple_alloc
 
179
{
 
180
public:
 
181
 
 
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;
 
187
 
 
188
   simple_alloc(){}
 
189
   simple_alloc(const simple_alloc&){}
 
190
 
 
191
   ~simple_alloc(){}
 
192
 
 
193
   pointer allocate(size_type n, const void* = 0) 
 
194
   {
 
195
      #ifdef BOOST_HAVE_SGI_ALLOCATOR
 
196
      return n != 0 ?
 
197
         reinterpret_cast<pointer>(alloc_type::allocate(n))
 
198
         : 0;
 
199
      #else
 
200
      return n != 0 ?
 
201
         reinterpret_cast<pointer>(::operator new(n))
 
202
         : 0;
 
203
      #endif
 
204
   }
 
205
 
 
206
   void deallocate(pointer p, size_type n) 
 
207
   {
 
208
      #ifdef BOOST_HAVE_SGI_ALLOCATOR
 
209
      assert( (p == 0) == (n == 0) );
 
210
      if (p != 0)
 
211
         alloc_type::deallocate((void*)p, n);
 
212
      #else
 
213
      assert( (p == 0) == (n == 0) );
 
214
      if (p != 0)
 
215
         ::operator delete((void*)p);
 
216
      #endif
 
217
   }
 
218
};
 
219
 
 
220
template <class T, class Base>
 
221
class allocator_adapter : public Base
 
222
{
 
223
public:
 
224
 
 
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;
 
233
 
 
234
   allocator_adapter(){}
 
235
   allocator_adapter(const base_type& x) : Base(x){}
 
236
   allocator_adapter& operator=(const base_type& x)
 
237
   {
 
238
      *(static_cast<base_type*>(this)) = x;
 
239
      return *this;
 
240
   }
 
241
 
 
242
   ~allocator_adapter(){}
 
243
 
 
244
   pointer address(reference x) { return &x; }
 
245
 
 
246
   const_pointer address(const_reference x) const { return &x; }
 
247
 
 
248
   pointer allocate(size_type n, const void* = 0) 
 
249
   {
 
250
      return n != 0 ?
 
251
         reinterpret_cast<pointer>(base_type::allocate(n * sizeof(value_type)))
 
252
         : 0;
 
253
   }
 
254
 
 
255
   void deallocate(pointer p, size_type n) 
 
256
   {
 
257
      assert( (p == 0) == (n == 0) );
 
258
      if (p != 0)
 
259
         static_cast<base_type*>(this)->deallocate((void*)p, n * sizeof(value_type));
 
260
   }
 
261
 
 
262
   size_type max_size() const
 
263
   { return size_t(-1) / sizeof(value_type); }
 
264
 
 
265
   void construct(pointer p, const T& val) const
 
266
   { allocator_construct(p, val); }
 
267
 
 
268
   void destroy(pointer p) const
 
269
   { allocator_destroy(p); }
 
270
};
 
271
 
 
272
template <class T, class A>
 
273
struct rebind_allocator
 
274
{
 
275
   typedef allocator_adapter<T, typename A::base_type> type;
 
276
};
 
277
 
 
278
} // namespace detail
 
279
} // namespace boost
 
280
 
 
281
#endif
 
282
 
 
283
#endif // include guard