Sierra Toolkit  Version of the Day
allocator_eastl.h
1 /*
2 Copyright (C) 2009-2010 Electronic Arts, Inc. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 
8 1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
14  its contributors may be used to endorse or promote products derived
15  from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
30 // EASTL/allocator.h
31 //
32 // Copyright (c) 2005, Electronic Arts. All rights reserved.
33 // Written and maintained by Paul Pedriana.
35 
36 
37 #ifndef EASTL_ALLOCATOR_H
38 #define EASTL_ALLOCATOR_H
39 
40 
41 #include <stk_util/util/config_eastl.h>
42 #include <stddef.h>
43 
44 
45 #ifdef _MSC_VER
46  #pragma warning(push)
47  #pragma warning(disable: 4189) // local variable is initialized but not referenced
48 #endif
49 
50 
51 namespace eastl
52 {
53 
58  #ifndef EASTL_ALLOCATOR_DEFAULT_NAME
59  #define EASTL_ALLOCATOR_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX // Unless the user overrides something, this is "EASTL".
60  #endif
61 
62 
68  {
69  MEM_TEMP = 0, // Low memory, not necessarily actually temporary.
70  MEM_PERM = 1 // High memory, for things that won't be unloaded.
71  };
72 
73 
81  class EASTL_API allocator
82  {
83  public:
84  EASTL_ALLOCATOR_EXPLICIT allocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME));
85  allocator(const allocator& x);
86  allocator(const allocator& x, const char* pName);
87 
88  allocator& operator=(const allocator& x);
89 
90  void* allocate(size_t n, int flags = 0);
91  void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0);
92  void deallocate(void* p, size_t n);
93 
94  const char* get_name() const;
95  void set_name(const char* pName);
96 
97  protected:
98  #if EASTL_NAME_ENABLED
99  const char* mpName; // Debug name, used to track memory.
100  #endif
101  };
102 
103  bool operator==(const allocator& a, const allocator& b);
104  bool operator!=(const allocator& a, const allocator& b);
105 
106  EASTL_API allocator* GetDefaultAllocator();
107  EASTL_API allocator* SetDefaultAllocator(allocator* pAllocator);
108 
109 
110 
128  template <typename Allocator>
129  inline Allocator* get_default_allocator(const Allocator*)
130  {
131  return NULL; // By default we return NULL; the user must make specialization of this function in order to provide their own implementation.
132  }
133 
134  inline EASTLAllocatorType* get_default_allocator(const EASTLAllocatorType*)
135  {
136  return EASTLAllocatorDefault(); // For the built-in allocator EASTLAllocatorType, we happen to already have a function for returning the default allocator instance, so we provide it.
137  }
138 
139 
145  inline void* default_allocfreemethod(size_t n, void* pBuffer, void* /*pContext*/)
146  {
147  EASTLAllocatorType* const pAllocator = EASTLAllocatorDefault();
148 
149  if(pBuffer) // If freeing...
150  {
151  EASTLFree(*pAllocator, pBuffer, n);
152  return NULL; // The return value is meaningless for the free.
153  }
154  else // allocating
155  return EASTLAlloc(*pAllocator, n);
156  }
157 
158 
166  template <typename Allocator>
167  void* allocate_memory(Allocator& a, size_t n, size_t alignment, size_t alignmentOffset)
168  {
169  if(alignment <= 8)
170  return EASTLAlloc(a, n);
171  return EASTLAllocAligned(a, n, alignment, alignmentOffset);
172  }
173 
174 } // namespace eastl
175 
176 
177 
178 
179 
180 #ifndef EASTL_USER_DEFINED_ALLOCATOR // If the user hasn't declared that he has defined a different allocator implementation elsewhere...
181 
182  #ifdef _MSC_VER
183  #pragma warning(push, 0)
184  #include <new>
185  #pragma warning(pop)
186  #else
187  #include <new>
188  #endif
189 
190  #if !EASTL_DLL // If building a regular library and not building EASTL as a DLL...
191  // It is expected that the application define the following
192  // versions of operator new for the application. Either that or the
193  // user needs to override the implementation of the allocator class.
194  void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags, const char* file, int line);
195  void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line);
196  #endif
197 
198  namespace eastl
199  {
200  inline allocator::allocator(const char* EASTL_NAME(pName))
201  {
202  #if EASTL_NAME_ENABLED
203  mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
204  #endif
205  }
206 
207 
208  inline allocator::allocator(const allocator& EASTL_NAME(alloc))
209  {
210  #if EASTL_NAME_ENABLED
211  mpName = alloc.mpName;
212  #endif
213  }
214 
215 
216  inline allocator::allocator(const allocator&, const char* EASTL_NAME(pName))
217  {
218  #if EASTL_NAME_ENABLED
219  mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
220  #endif
221  }
222 
223 
224  inline allocator& allocator::operator=(const allocator& EASTL_NAME(alloc))
225  {
226  #if EASTL_NAME_ENABLED
227  mpName = alloc.mpName;
228  #endif
229  return *this;
230  }
231 
232 
233  inline const char* allocator::get_name() const
234  {
235  #if EASTL_NAME_ENABLED
236  return mpName;
237  #else
238  return EASTL_ALLOCATOR_DEFAULT_NAME;
239  #endif
240  }
241 
242 
243  inline void allocator::set_name(const char* EASTL_NAME(pName))
244  {
245  #if EASTL_NAME_ENABLED
246  mpName = pName;
247  #endif
248  }
249 
250 
251  inline void* allocator::allocate(size_t n, int flags)
252  {
253  #if EASTL_NAME_ENABLED
254  #define pName mpName
255  #else
256  #define pName EASTL_ALLOCATOR_DEFAULT_NAME
257  #endif
258 
259  #if EASTL_DLL
260  // We currently have no support for implementing flags when
261  // using the C runtime library operator new function. The user
262  // can use SetDefaultAllocator to override the default allocator.
263  (void)flags;
264  return ::new char[n];
265  #elif (EASTL_DEBUGPARAMS_LEVEL <= 0)
266  return ::new((char*)0, flags, 0, (char*)0, 0) char[n];
267  #elif (EASTL_DEBUGPARAMS_LEVEL == 1)
268  return ::new( pName, flags, 0, (char*)0, 0) char[n];
269  #else
270  return ::new( pName, flags, 0, __FILE__, __LINE__) char[n];
271  #endif
272  }
273 
274 
275  inline void* allocator::allocate(size_t n, size_t alignment, size_t offset, int flags)
276  {
277  #if EASTL_DLL
278  // We have a problem here. We cannot support alignment, as we don't have access
279  // to a memory allocator that can provide aligned memory. The C++ standard doesn't
280  // recognize such a thing. The user will need to call SetDefaultAllocator to
281  // provide an alloator which supports alignment.
282  EASTL_ASSERT(alignment <= 8); // 8 (sizeof(double)) is the standard alignment returned by operator new.
283  (void)alignment; (void)offset; (void)flags;
284  return new char[n];
285  #elif (EASTL_DEBUGPARAMS_LEVEL <= 0)
286  return ::new(alignment, offset, (char*)0, flags, 0, (char*)0, 0) char[n];
287  #elif (EASTL_DEBUGPARAMS_LEVEL == 1)
288  return ::new(alignment, offset, pName, flags, 0, (char*)0, 0) char[n];
289  #else
290  return ::new(alignment, offset, pName, flags, 0, __FILE__, __LINE__) char[n];
291  #endif
292 
293  #undef pName // See above for the definition of this.
294  }
295 
296 
297  inline void allocator::deallocate(void* p, size_t)
298  {
299  delete[] (char*)p;
300  }
301 
302 
303  inline bool operator==(const allocator&, const allocator&)
304  {
305  return true; // All allocators are considered equal, as they merely use global new/delete.
306  }
307 
308 
309  inline bool operator!=(const allocator&, const allocator&)
310  {
311  return false; // All allocators are considered equal, as they merely use global new/delete.
312  }
313 
314 
315  } // namespace eastl
316 
317 
318 #endif // EASTL_USER_DEFINED_ALLOCATOR
319 
320 
321 #ifdef _MSC_VER
322  #pragma warning(pop)
323 #endif
324 
325 
326 #endif // Header include guard
void * default_allocfreemethod(size_t n, void *pBuffer, void *)
Allocator * get_default_allocator(const Allocator *)
void * allocate_memory(Allocator &a, size_t n, size_t alignment, size_t alignmentOffset)
EA Standard Template Library.