]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/netradiant-src/libs/memory/allocator.h
Move all other sources in a separate subfolder
[voretournament/voretournament.git] / misc / mediasource / netradiant-src / 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
27 #if 0
28
29 #define DefaultAllocator std::allocator
30
31 #else
32
33 /// \brief An allocator that uses c++ new/delete.
34 /// Compliant with the std::allocator interface.
35 template<typename Type>
36 class DefaultAllocator
37 {
38 public:
39
40   typedef Type value_type;
41   typedef value_type* pointer;
42   typedef const Type* const_pointer;
43   typedef Type& reference;
44   typedef const Type& const_reference;
45   typedef size_t size_type;
46   typedef ptrdiff_t difference_type;
47
48   template<typename Other>
49   struct rebind
50   {
51     typedef DefaultAllocator<Other> other;
52   };
53
54   DefaultAllocator()
55   {
56   }
57   DefaultAllocator(const DefaultAllocator<Type>&)
58   {
59   }
60   template<typename Other> DefaultAllocator(const DefaultAllocator<Other>&)
61   {
62   }
63   ~DefaultAllocator()
64   {
65   }
66
67   pointer address(reference instance) const
68   {
69     return &instance;
70   }
71   const_pointer address(const_reference instance) const
72   {
73     return &instance;
74   }
75   Type* allocate(size_type size, const void* = 0)
76   { 
77     return static_cast<Type*>(::operator new(size * sizeof(Type)));
78   }
79   void deallocate(pointer p, size_type)
80   {
81     ::operator delete(p);
82   }
83   size_type max_size() const
84   {
85                 return std::size_t(-1) / sizeof (Type);
86   }
87   void construct(pointer p, const Type& value)
88   {
89     new(p) Type(value);
90   }
91   void destroy(pointer p)
92   {
93     p->~Type();
94   }
95 };
96
97 template<typename Type, typename Other>
98 inline bool operator==(const DefaultAllocator<Type>&, const DefaultAllocator<Other>&)
99
100     return true;
101 }
102 template<typename Type, typename OtherAllocator>
103 inline bool operator==(const DefaultAllocator<Type>&, const OtherAllocator&)
104
105     return false; 
106 }
107
108 #endif
109
110
111 template<typename Type>
112 class NamedAllocator : public DefaultAllocator<Type>
113 {
114   typedef DefaultAllocator<Type> allocator_type;
115
116   const char* m_name;
117 public:
118
119   typedef Type value_type;
120   typedef value_type* pointer;
121   typedef const Type* const_pointer;
122   typedef Type& reference;
123   typedef const Type& const_reference;
124   typedef size_t size_type;
125   typedef ptrdiff_t difference_type;
126
127   template<typename Other>
128   struct rebind
129   {
130     typedef NamedAllocator<Other> other;
131   };
132
133   explicit NamedAllocator(const char* name) : m_name(name)
134   {
135   }
136   NamedAllocator(const NamedAllocator<Type>& other) : m_name(other.m_name)
137   {
138   }
139   template<typename Other> NamedAllocator(const NamedAllocator<Other>& other) : m_name(other.m_name)
140   {
141   }
142   ~NamedAllocator()
143   {
144   }
145
146   pointer address(reference instance) const
147   {
148     return allocator_type::address(instance);
149   }
150   const_pointer address(const_reference instance) const
151   {
152     return allocator_type::address(instance);
153   }
154   Type* allocate(size_type size, const void* = 0)
155   { 
156     return allocator_type::allocate(size);
157   }
158   void deallocate(pointer p, size_type size)
159   {
160     allocator_type::deallocate(p, size);
161   }
162   size_type max_size() const
163   {
164     return allocator_type::max_size();
165   }
166   void construct(pointer p, const Type& value)
167   {
168     allocator_type::construct(p, value);
169   }
170   void destroy(pointer p)
171   {
172     allocator_type::destroy(p);
173   }
174
175   template<typename Other>
176   bool operator==(const NamedAllocator<Other>& other)
177   {
178     return true;
179   }
180
181   // returns true if the allocators are not interchangeable
182   template<typename Other>
183   bool operator!=(const NamedAllocator<Other>& other)
184   {
185     return false;
186   }
187 };
188
189
190
191 #include <algorithm>
192 #include "generic/object.h"
193
194
195
196 template<typename Type>
197 class DefaultConstruct
198 {
199 public:
200   void operator()(Type& t)
201   {
202     constructor(t);
203   }
204 };
205
206 template<typename Type, typename T1>
207 class Construct
208 {
209   const T1& other;
210 public:
211   Construct(const T1& other_) : other(other_)
212   {
213   }
214   void operator()(Type& t)
215   {
216     constructor(t, other);
217   }
218 };
219
220 template<typename Type>
221 class Destroy
222 {
223 public:
224   void operator()(Type& t)
225   {
226     destructor(t);
227   }
228 };
229
230 template<typename Type, typename Allocator = DefaultAllocator<Type> >
231 class New : public Allocator
232 {
233 public:
234   New()
235   {
236   }
237   explicit New(const Allocator& allocator) : Allocator(allocator)
238   {
239   }
240
241   Type* scalar()
242   {
243     return new(Allocator::allocate(1)) Type();
244   }
245   template<typename T1>
246   Type* scalar(const T1& t1)
247   {
248     return new(Allocator::allocate(1)) Type(t1);
249   }
250   template<typename T1, typename T2>
251   Type* scalar(const T1& t1, const T2& t2)
252   {
253     return new(Allocator::allocate(1)) Type(t1, t2);
254   }
255   template<typename T1, typename T2, typename T3>
256   Type* scalar(const T1& t1, const T2& t2, const T3& t3)
257   {
258     return new(Allocator::allocate(1)) Type(t1, t2, t3);
259   }
260   template<typename T1, typename T2, typename T3, typename T4>
261   Type* scalar(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
262   {
263     return new(Allocator::allocate(1)) Type(t1, t2, t3, t4);
264   }
265   template<typename T1, typename T2, typename T3, typename T4, typename T5>
266   Type* scalar(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
267   {
268     return new(Allocator::allocate(1)) Type(t1, t2, t3, t4, t5);
269   }
270   Type* vector(std::size_t size)
271   {
272 #if 1
273     Type* p = Allocator::allocate(size);
274     std::for_each(p, p + size, DefaultConstruct<Type>());
275     return p;
276 #else
277     // this does not work with msvc71 runtime
278     return new(Allocator::allocate(size)) Type[size];
279 #endif
280   }
281   template<typename T1>
282   Type* vector(std::size_t size, const T1& t1)
283   {
284     Type* p = Allocator::allocate(size);
285     std::for_each(p, p + size, Construct<Type, T1>(t1));
286     return p;
287   }
288 };
289
290 template<typename Type, typename Allocator = DefaultAllocator<Type> >
291 class Delete : public Allocator
292 {
293 public:
294   Delete()
295   {
296   }
297   explicit Delete(const Allocator& allocator) : Allocator(allocator)
298   {
299   }
300
301   void scalar(Type* p)
302   {
303     if(p != 0)
304     {
305       p->~Type();
306       Allocator::deallocate(p, 1);
307     }
308   }
309   void vector(Type* p, std::size_t size)
310   {
311     // '::operator delete' handles null
312     // 'std::allocator::deallocate' requires non-null
313     if(p != 0) 
314     {
315       std::for_each(p, p + size, Destroy<Type>());
316       Allocator::deallocate(p, size);
317     }
318   }
319 };
320
321
322 template<typename Type>
323 class NamedNew
324 {
325 public:
326   typedef New<Type, NamedAllocator<Type> > type;
327 };
328
329 template<typename Type>
330 class NamedDelete
331 {
332 public:
333   typedef Delete<Type, NamedAllocator<Type> > type;
334 };
335
336 #endif