Nugget
core_allocator_adapter.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
6 // Implements an EASTL allocator that uses an ICoreAllocator.
7 // However, this header file is not dependent on ICoreAllocator or its package.
9 
10 #ifndef EASTL_CORE_ALLOCATOR_ADAPTER_H
11 #define EASTL_CORE_ALLOCATOR_ADAPTER_H
12 
13 #if EASTL_CORE_ALLOCATOR_ENABLED
14 
15 
16 #include <EASTL/internal/config.h>
17 
18 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
19  #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
20 #endif
21 
22 
29 #ifndef EASTL_CORE_ALLOCATOR_ADAPTER_GET_DEFAULT_CORE_ALLOCATOR
30  #define EASTL_CORE_ALLOCATOR_ADAPTER_GET_DEFAULT_CORE_ALLOCATOR AllocatorType::GetDefaultAllocator
31 #endif
32 
33 
34 
35 namespace EA
36 {
37  namespace Allocator
38  {
81  template<class AllocatorType>
82  class CoreAllocatorAdapter
83  {
84  public:
85  typedef CoreAllocatorAdapter<AllocatorType> this_type;
86 
87  public:
88  // To do: Make this constructor explicit, when there is no known code dependent on it being otherwise.
89  CoreAllocatorAdapter(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME), AllocatorType* pAllocator = EASTL_CORE_ALLOCATOR_ADAPTER_GET_DEFAULT_CORE_ALLOCATOR());
90  CoreAllocatorAdapter(const char* pName, AllocatorType* pAllocator, int flags);
91  CoreAllocatorAdapter(const CoreAllocatorAdapter& x);
92  CoreAllocatorAdapter(const CoreAllocatorAdapter& x, const char* pName);
93 
94  CoreAllocatorAdapter& operator=(const CoreAllocatorAdapter& x);
95 
96  void* allocate(size_t n, int flags = 0);
97  void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0);
98  void deallocate(void* p, size_t n);
99 
100  AllocatorType* get_allocator() const;
101  void set_allocator(AllocatorType* pAllocator);
102 
103  int get_flags() const;
104  void set_flags(int flags);
105 
106  const char* get_name() const;
107  void set_name(const char* pName);
108 
109  public: // Public because otherwise VC++ generates (possibly invalid) warnings about inline friend template specializations.
110  AllocatorType* mpCoreAllocator;
111  int mnFlags; // Allocation flags. See ICoreAllocator/AllocFlags.
112 
113  #if EASTL_NAME_ENABLED
114  const char* mpName; // Debug name, used to track memory.
115  #endif
116  };
117 
118  template<class AllocatorType>
119  bool operator==(const CoreAllocatorAdapter<AllocatorType>& a, const CoreAllocatorAdapter<AllocatorType>& b);
120 
121  template<class AllocatorType>
122  bool operator!=(const CoreAllocatorAdapter<AllocatorType>& a, const CoreAllocatorAdapter<AllocatorType>& b);
123 
124 
125 
134  class ICoreAllocator;
135  class EASTLCoreAllocatorImpl;
136 
137  typedef CoreAllocatorAdapter<ICoreAllocator> EASTLICoreAllocatorAdapter;
138  typedef CoreAllocatorAdapter<EASTLCoreAllocatorImpl> EASTLCoreAllocatorAdapter;
139  typedef EASTLICoreAllocatorAdapter EASTLICoreAllocator; // for backwards compatibility
140 
141 
142 
150  template <class AllocatorType>
151  class CoreDeleterAdapter
152  {
153  public:
154  typedef CoreDeleterAdapter<AllocatorType> this_type;
155  AllocatorType* mpCoreAllocator;
156 
157  public:
158  CoreDeleterAdapter(AllocatorType* pAllocator = EASTL_CORE_ALLOCATOR_ADAPTER_GET_DEFAULT_CORE_ALLOCATOR()) EA_NOEXCEPT
159  : mpCoreAllocator(pAllocator) {}
160 
161  ~CoreDeleterAdapter() EA_NOEXCEPT {}
162 
163  template <typename T>
164  void operator()(T* p)
165  {
166  p->~T();
167  mpCoreAllocator->Free(p);
168  }
169 
170  CoreDeleterAdapter(const CoreDeleterAdapter& in) { mpCoreAllocator = in.mpCoreAllocator; }
171 
172  CoreDeleterAdapter(CoreDeleterAdapter&& in)
173  {
174  mpCoreAllocator = in.mpCoreAllocator;
175  in.mpCoreAllocator = nullptr;
176  }
177 
178  CoreDeleterAdapter& operator=(const CoreDeleterAdapter& in)
179  {
180  mpCoreAllocator = in.mpCoreAllocator;
181  return *this;
182  }
183 
184  CoreDeleterAdapter& operator=(CoreDeleterAdapter&& in)
185  {
186  mpCoreAllocator = in.mpCoreAllocator;
187  in.mpCoreAllocator = nullptr;
188  return *this;
189  }
190  };
191 
192 
193 
201  typedef CoreDeleterAdapter<ICoreAllocator> EASTLICoreDeleterAdapter;
202  typedef CoreDeleterAdapter<EASTLCoreAllocatorImpl> EASTLCoreDeleterAdapter;
203 
204  } // namespace Allocator
205 
206 } // namespace EA
207 
208 
209 
210 
211 
213 // Inlines
215 
216 namespace EA
217 {
218  namespace Allocator
219  {
220  template<class AllocatorType>
221  inline CoreAllocatorAdapter<AllocatorType>::CoreAllocatorAdapter(const char* EASTL_NAME(pName), AllocatorType* pCoreAllocator)
222  : mpCoreAllocator(pCoreAllocator), mnFlags(0)
223  {
224  #if EASTL_NAME_ENABLED
225  mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
226  #endif
227  }
228 
229  template<class AllocatorType>
230  inline CoreAllocatorAdapter<AllocatorType>::CoreAllocatorAdapter(const char* EASTL_NAME(pName), AllocatorType* pCoreAllocator, int flags)
231  : mpCoreAllocator(pCoreAllocator), mnFlags(flags)
232  {
233  #if EASTL_NAME_ENABLED
234  mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
235  #endif
236  }
237 
238  template<class AllocatorType>
239  inline CoreAllocatorAdapter<AllocatorType>::CoreAllocatorAdapter(const CoreAllocatorAdapter& x)
240  : mpCoreAllocator(x.mpCoreAllocator), mnFlags(x.mnFlags)
241  {
242  #if EASTL_NAME_ENABLED
243  mpName = x.mpName;
244  #endif
245  }
246 
247  template<class AllocatorType>
248  inline CoreAllocatorAdapter<AllocatorType>::CoreAllocatorAdapter(const CoreAllocatorAdapter& x, const char* EASTL_NAME(pName))
249  : mpCoreAllocator(x.mpCoreAllocator), mnFlags(x.mnFlags)
250  {
251  #if EASTL_NAME_ENABLED
252  mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
253  #endif
254  }
255 
256  template<class AllocatorType>
257  inline CoreAllocatorAdapter<AllocatorType>& CoreAllocatorAdapter<AllocatorType>::operator=(const CoreAllocatorAdapter& x)
258  {
259  mpCoreAllocator = x.mpCoreAllocator;
260  mnFlags = x.mnFlags;
261 
262  #if EASTL_NAME_ENABLED
263  mpName = x.mpName;
264  #endif
265 
266  return *this;
267  }
268 
269  template<class AllocatorType>
270  inline void* CoreAllocatorAdapter<AllocatorType>::allocate(size_t n, int /*flags*/)
271  {
272  // It turns out that EASTL itself doesn't use the flags parameter,
273  // whereas the user here might well want to specify a flags
274  // parameter. So we use ours instead of the one passed in.
275  return mpCoreAllocator->Alloc(n, EASTL_NAME_VAL(mpName), (unsigned)mnFlags);
276  }
277 
278  template<class AllocatorType>
279  inline void* CoreAllocatorAdapter<AllocatorType>::allocate(size_t n, size_t alignment, size_t offset, int /*flags*/)
280  {
281  // It turns out that EASTL itself doesn't use the flags parameter,
282  // whereas the user here might well want to specify a flags
283  // parameter. So we use ours instead of the one passed in.
284  return mpCoreAllocator->Alloc(n, EASTL_NAME_VAL(mpName), (unsigned)mnFlags, (unsigned)alignment, (unsigned)offset);
285  }
286 
287  template<class AllocatorType>
288  inline void CoreAllocatorAdapter<AllocatorType>::deallocate(void* p, size_t n)
289  {
290  return mpCoreAllocator->Free(p, n);
291  }
292 
293  template<class AllocatorType>
294  inline AllocatorType* CoreAllocatorAdapter<AllocatorType>::get_allocator() const
295  {
296  return mpCoreAllocator;
297  }
298 
299  template<class AllocatorType>
300  inline void CoreAllocatorAdapter<AllocatorType>::set_allocator(AllocatorType* pAllocator)
301  {
302  mpCoreAllocator = pAllocator;
303  }
304 
305  template<class AllocatorType>
306  inline int CoreAllocatorAdapter<AllocatorType>::get_flags() const
307  {
308  return mnFlags;
309  }
310 
311  template<class AllocatorType>
312  inline void CoreAllocatorAdapter<AllocatorType>::set_flags(int flags)
313  {
314  mnFlags = flags;
315  }
316 
317  template<class AllocatorType>
318  inline const char* CoreAllocatorAdapter<AllocatorType>::get_name() const
319  {
320  #if EASTL_NAME_ENABLED
321  return mpName;
322  #else
323  return EASTL_ALLOCATOR_DEFAULT_NAME;
324  #endif
325  }
326 
327  template<class AllocatorType>
328  inline void CoreAllocatorAdapter<AllocatorType>::set_name(const char* pName)
329  {
330  #if EASTL_NAME_ENABLED
331  mpName = pName;
332  #else
333  (void)pName;
334  #endif
335  }
336 
337 
338 
339  template<class AllocatorType>
340  inline bool operator==(const CoreAllocatorAdapter<AllocatorType>& a, const CoreAllocatorAdapter<AllocatorType>& b)
341  {
342  return (a.mpCoreAllocator == b.mpCoreAllocator) &&
343  (a.mnFlags == b.mnFlags);
344  }
345 
346  template<class AllocatorType>
347  inline bool operator!=(const CoreAllocatorAdapter<AllocatorType>& a, const CoreAllocatorAdapter<AllocatorType>& b)
348  {
349  return (a.mpCoreAllocator != b.mpCoreAllocator) ||
350  (a.mnFlags != b.mnFlags);
351  }
352 
353 
354  } // namespace Allocator
355 
356 } // namespace EA
357 
358 
359 #endif // EASTL_CORE_ALLOCATOR_ENABLED
360 #endif // Header include guard
361 
362 
363 
364 
365 
366 
367 
368