]> icculus.org git repositories - divverent/netradiant.git/blob - libs/memory/allocator.h
fix compile on arch linux
[divverent/netradiant.git] / libs / memory / allocator.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_MEMORY_ALLOCATOR_H)
23 #define INCLUDED_MEMORY_ALLOCATOR_H
24
25 #include <memory>
26 #include <stddef.h>
27
28 #if 0
29
30 #define DefaultAllocator std::allocator
31
32 #else
33
34 /// \brief An allocator that uses c++ new/delete.
35 /// Compliant with the std::allocator interface.
36 template<typename Type>
37 class DefaultAllocator
38 {
39 public:
40
41   typedef Type value_type;
42   typedef value_type* pointer;
43   typedef const Type* const_pointer;
44   typedef Type& reference;
45   typedef const Type& const_reference;
46   typedef size_t size_type;
47   typedef ptrdiff_t difference_type;
48
49   template<typename Other>
50   struct rebind
51   {
52     typedef DefaultAllocator<Other> other;
53   };
54
55   DefaultAllocator()
56   {
57   }
58   DefaultAllocator(const DefaultAllocator<Type>&)
59   {
60   }
61   template<typename Other> DefaultAllocator(const DefaultAllocator<Other>&)
62   {
63   }
64   ~DefaultAllocator()
65   {
66   }
67
68   pointer address(reference instance) const
69   {
70     return &instance;
71   }
72   const_pointer address(const_reference instance) const
73   {
74     return &instance;
75   }
76   Type* allocate(size_type size, const void* = 0)
77   { 
78     return static_cast<Type*>(::operator new(size * sizeof(Type)));
79   }
80   void deallocate(pointer p, size_type)
81   {
82     ::operator delete(p);
83   }
84   size_type max_size() const
85   {
86                 return std::size_t(-1) / sizeof (Type);
87   }
88   void construct(pointer p, const Type& value)
89   {
90     new(p) Type(value);
91   }
92   void destroy(pointer p)
93   {
94     p->~Type();
95   }
96 };
97
98 template<typename Type, typename Other>
99 inline bool operator==(const DefaultAllocator<Type>&, const DefaultAllocator<Other>&)
100
101     return true;
102 }
103 template<typename Type, typename OtherAllocator>
104 inline bool operator==(const DefaultAllocator<Type>&, const OtherAllocator&)
105
106     return false; 
107 }
108
109 #endif
110
111
112 template<typename Type>
113 class NamedAllocator : public DefaultAllocator<Type>
114 {
115   typedef DefaultAllocator<Type> allocator_type;
116
117   const char* m_name;
118 public:
119
120   typedef Type value_type;
121   typedef value_type* pointer;
122   typedef const Type* const_pointer;
123   typedef Type& reference;
124   typedef const Type& const_reference;
125   typedef size_t size_type;
126   typedef ptrdiff_t difference_type;
127
128   template<typename Other>
129   struct rebind
130   {
131     typedef NamedAllocator<Other> other;
132   };
133
134   explicit NamedAllocator(const char* name) : m_name(name)
135   {
136   }
137   NamedAllocator(const NamedAllocator<Type>& other) : m_name(other.m_name)
138   {
139   }
140   template<typename Other> NamedAllocator(const NamedAllocator<Other>& other) : m_name(other.m_name)
141   {
142   }
143   ~NamedAllocator()
144   {
145   }
146
147   pointer address(reference instance) const
148   {
149     return allocator_type::address(instance);
150   }
151   const_pointer address(const_reference instance) const
152   {
153     return allocator_type::address(instance);
154   }
155   Type* allocate(size_type size, const void* = 0)
156   { 
157     return allocator_type::allocate(size);
158   }
159   void deallocate(pointer p, size_type size)
160   {
161     allocator_type::deallocate(p, size);
162   }
163   size_type max_size() const
164   {
165     return allocator_type::max_size();
166   }
167   void construct(pointer p, const Type& value)
168   {
169     allocator_type::construct(p, value);
170   }
171   void destroy(pointer p)
172   {
173     allocator_type::destroy(p);
174   }
175
176   template<typename Other>
177   bool operator==(const NamedAllocator<Other>& other)
178   {
179     return true;
180   }
181
182   // returns true if the allocators are not interchangeable
183   template<typename Other>
184   bool operator!=(const NamedAllocator<Other>& other)
185   {
186     return false;
187   }
188 };
189
190
191
192 #include <algorithm>
193 #include "generic/object.h"
194
195
196
197 template<typename Type>
198 class DefaultConstruct
199 {
200 public:
201   void operator()(Type& t)
202   {
203     constructor(t);
204   }
205 };
206
207 template<typename Type, typename T1>
208 class Construct
209 {
210   const T1& other;
211 public:
212   Construct(const T1& other_) : other(other_)
213   {
214   }
215   void operator()(Type& t)
216   {
217     constructor(t, other);
218   }
219 };
220
221 template<typename Type>
222 class Destroy
223 {
224 public:
225   void operator()(Type& t)
226   {
227     destructor(t);
228   }
229 };
230
231 template<typename Type, typename Allocator = DefaultAllocator<Type> >
232 class New : public Allocator
233 {
234 public:
235   New()
236   {
237   }
238   explicit New(const Allocator& allocator) : Allocator(allocator)
239   {
240   }
241
242   Type* scalar()
243   {
244     return new(Allocator::allocate(1)) Type();
245   }
246   template<typename T1>
247   Type* scalar(const T1& t1)
248   {
249     return new(Allocator::allocate(1)) Type(t1);
250   }
251   template<typename T1, typename T2>
252   Type* scalar(const T1& t1, const T2& t2)
253   {
254     return new(Allocator::allocate(1)) Type(t1, t2);
255   }
256   template<typename T1, typename T2, typename T3>
257   Type* scalar(const T1& t1, const T2& t2, const T3& t3)
258   {
259     return new(Allocator::allocate(1)) Type(t1, t2, t3);
260   }
261   template<typename T1, typename T2, typename T3, typename T4>
262   Type* scalar(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
263   {
264     return new(Allocator::allocate(1)) Type(t1, t2, t3, t4);
265   }
266   template<typename T1, typename T2, typename T3, typename T4, typename T5>
267   Type* scalar(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
268   {
269     return new(Allocator::allocate(1)) Type(t1, t2, t3, t4, t5);
270   }
271   Type* vector(std::size_t size)
272   {
273 #if 1
274     Type* p = Allocator::allocate(size);
275     std::for_each(p, p + size, DefaultConstruct<Type>());
276     return p;
277 #else
278     // this does not work with msvc71 runtime
279     return new(Allocator::allocate(size)) Type[size];
280 #endif
281   }
282   template<typename T1>
283   Type* vector(std::size_t size, const T1& t1)
284   {
285     Type* p = Allocator::allocate(size);
286     std::for_each(p, p + size, Construct<Type, T1>(t1));
287     return p;
288   }
289 };
290
291 template<typename Type, typename Allocator = DefaultAllocator<Type> >
292 class Delete : public Allocator
293 {
294 public:
295   Delete()
296   {
297   }
298   explicit Delete(const Allocator& allocator) : Allocator(allocator)
299   {
300   }
301
302   void scalar(Type* p)
303   {
304     if(p != 0)
305     {
306       p->~Type();
307       Allocator::deallocate(p, 1);
308     }
309   }
310   void vector(Type* p, std::size_t size)
311   {
312     // '::operator delete' handles null
313     // 'std::allocator::deallocate' requires non-null
314     if(p != 0) 
315     {
316       std::for_each(p, p + size, Destroy<Type>());
317       Allocator::deallocate(p, size);
318     }
319   }
320 };
321
322
323 template<typename Type>
324 class NamedNew
325 {
326 public:
327   typedef New<Type, NamedAllocator<Type> > type;
328 };
329
330 template<typename Type>
331 class NamedDelete
332 {
333 public:
334   typedef Delete<Type, NamedAllocator<Type> > type;
335 };
336
337 #endif