Sierra Toolkit Version of the Day
allocator_eastl.h
00001 /*
00002 Copyright (C) 2009-2010 Electronic Arts, Inc.  All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions
00006 are met:
00007 
00008 1.  Redistributions of source code must retain the above copyright
00009     notice, this list of conditions and the following disclaimer.
00010 2.  Redistributions in binary form must reproduce the above copyright
00011     notice, this list of conditions and the following disclaimer in the
00012     documentation and/or other materials provided with the distribution.
00013 3.  Neither the name of Electronic Arts, Inc. ("EA") nor the names of
00014     its contributors may be used to endorse or promote products derived
00015     from this software without specific prior written permission.
00016 
00017 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
00018 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
00021 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00030 // EASTL/allocator.h
00031 //
00032 // Copyright (c) 2005, Electronic Arts. All rights reserved.
00033 // Written and maintained by Paul Pedriana.
00035 
00036 
00037 #ifndef EASTL_ALLOCATOR_H
00038 #define EASTL_ALLOCATOR_H
00039 
00040 
00041 #include <stk_util/util/config_eastl.h>
00042 #include <stddef.h>
00043 
00044 
00045 #ifdef _MSC_VER
00046     #pragma warning(push)
00047     #pragma warning(disable: 4189) // local variable is initialized but not referenced
00048 #endif
00049 
00050 
00051 namespace eastl
00052 {
00053 
00058     #ifndef EASTL_ALLOCATOR_DEFAULT_NAME
00059         #define EASTL_ALLOCATOR_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX // Unless the user overrides something, this is "EASTL".
00060     #endif
00061 
00062 
00067     enum alloc_flags
00068     {
00069         MEM_TEMP = 0, // Low memory, not necessarily actually temporary.
00070         MEM_PERM = 1  // High memory, for things that won't be unloaded.
00071     };
00072 
00073 
00081     class EASTL_API allocator
00082     {
00083     public:
00084         EASTL_ALLOCATOR_EXPLICIT allocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME));
00085         allocator(const allocator& x);
00086         allocator(const allocator& x, const char* pName);
00087 
00088         allocator& operator=(const allocator& x);
00089 
00090         void* allocate(size_t n, int flags = 0);
00091         void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0);
00092         void  deallocate(void* p, size_t n);
00093 
00094         const char* get_name() const;
00095         void        set_name(const char* pName);
00096 
00097     protected:
00098         #if EASTL_NAME_ENABLED
00099             const char* mpName; // Debug name, used to track memory.
00100         #endif
00101     };
00102 
00103     bool operator==(const allocator& a, const allocator& b);
00104     bool operator!=(const allocator& a, const allocator& b);
00105 
00106     EASTL_API allocator* GetDefaultAllocator();
00107     EASTL_API allocator* SetDefaultAllocator(allocator* pAllocator);
00108 
00109 
00110 
00128     template <typename Allocator>
00129     inline Allocator* get_default_allocator(const Allocator*)
00130     {
00131         return NULL; // By default we return NULL; the user must make specialization of this function in order to provide their own implementation.
00132     }
00133 
00134     inline EASTLAllocatorType* get_default_allocator(const EASTLAllocatorType*)
00135     {
00136         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.
00137     }
00138 
00139 
00145     inline void* default_allocfreemethod(size_t n, void* pBuffer, void* /*pContext*/)
00146     {
00147         EASTLAllocatorType* const pAllocator = EASTLAllocatorDefault();
00148 
00149         if(pBuffer) // If freeing...
00150         {
00151             EASTLFree(*pAllocator, pBuffer, n);
00152             return NULL;  // The return value is meaningless for the free.
00153         }
00154         else // allocating
00155             return EASTLAlloc(*pAllocator, n);
00156     }
00157 
00158 
00166     template <typename Allocator>
00167     void* allocate_memory(Allocator& a, size_t n, size_t alignment, size_t alignmentOffset)
00168     {
00169         if(alignment <= 8)
00170             return EASTLAlloc(a, n);
00171         return EASTLAllocAligned(a, n, alignment, alignmentOffset);
00172     }
00173 
00174 } // namespace eastl
00175 
00176 
00177 
00178 
00179 
00180 #ifndef EASTL_USER_DEFINED_ALLOCATOR // If the user hasn't declared that he has defined a different allocator implementation elsewhere...
00181 
00182     #ifdef _MSC_VER
00183         #pragma warning(push, 0)
00184         #include <new>
00185         #pragma warning(pop)
00186     #else
00187         #include <new>
00188     #endif
00189 
00190     #if !EASTL_DLL // If building a regular library and not building EASTL as a DLL...
00191         // It is expected that the application define the following
00192         // versions of operator new for the application. Either that or the
00193         // user needs to override the implementation of the allocator class.
00194         void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags, const char* file, int line);
00195         void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line);
00196     #endif
00197 
00198     namespace eastl
00199     {
00200         inline allocator::allocator(const char* EASTL_NAME(pName))
00201         {
00202             #if EASTL_NAME_ENABLED
00203                 mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
00204             #endif
00205         }
00206 
00207 
00208         inline allocator::allocator(const allocator& EASTL_NAME(alloc))
00209         {
00210             #if EASTL_NAME_ENABLED
00211                 mpName = alloc.mpName;
00212             #endif
00213         }
00214 
00215 
00216         inline allocator::allocator(const allocator&, const char* EASTL_NAME(pName))
00217         {
00218             #if EASTL_NAME_ENABLED
00219                 mpName = pName ? pName : EASTL_ALLOCATOR_DEFAULT_NAME;
00220             #endif
00221         }
00222 
00223 
00224         inline allocator& allocator::operator=(const allocator& EASTL_NAME(alloc))
00225         {
00226             #if EASTL_NAME_ENABLED
00227                 mpName = alloc.mpName;
00228             #endif
00229             return *this;
00230         }
00231 
00232 
00233         inline const char* allocator::get_name() const
00234         {
00235             #if EASTL_NAME_ENABLED
00236                 return mpName;
00237             #else
00238                 return EASTL_ALLOCATOR_DEFAULT_NAME;
00239             #endif
00240         }
00241 
00242 
00243         inline void allocator::set_name(const char* EASTL_NAME(pName))
00244         {
00245             #if EASTL_NAME_ENABLED
00246                 mpName = pName;
00247             #endif
00248         }
00249 
00250 
00251         inline void* allocator::allocate(size_t n, int flags)
00252         {
00253             #if EASTL_NAME_ENABLED
00254                 #define pName mpName
00255             #else
00256                 #define pName EASTL_ALLOCATOR_DEFAULT_NAME
00257             #endif
00258 
00259             #if EASTL_DLL
00260                 // We currently have no support for implementing flags when
00261                 // using the C runtime library operator new function. The user
00262                 // can use SetDefaultAllocator to override the default allocator.
00263                 (void)flags;
00264                 return ::new char[n];
00265             #elif (EASTL_DEBUGPARAMS_LEVEL <= 0)
00266                 return ::new((char*)0, flags, 0, (char*)0,        0) char[n];
00267             #elif (EASTL_DEBUGPARAMS_LEVEL == 1)
00268                 return ::new(   pName, flags, 0, (char*)0,        0) char[n];
00269             #else
00270                 return ::new(   pName, flags, 0, __FILE__, __LINE__) char[n];
00271             #endif
00272         }
00273 
00274 
00275         inline void* allocator::allocate(size_t n, size_t alignment, size_t offset, int flags)
00276         {
00277             #if EASTL_DLL
00278                 // We have a problem here. We cannot support alignment, as we don't have access
00279                 // to a memory allocator that can provide aligned memory. The C++ standard doesn't
00280                 // recognize such a thing. The user will need to call SetDefaultAllocator to
00281                 // provide an alloator which supports alignment.
00282                 EASTL_ASSERT(alignment <= 8); // 8 (sizeof(double)) is the standard alignment returned by operator new.
00283                 (void)alignment; (void)offset; (void)flags;
00284                 return new char[n];
00285             #elif (EASTL_DEBUGPARAMS_LEVEL <= 0)
00286                 return ::new(alignment, offset, (char*)0, flags, 0, (char*)0,        0) char[n];
00287             #elif (EASTL_DEBUGPARAMS_LEVEL == 1)
00288                 return ::new(alignment, offset,    pName, flags, 0, (char*)0,        0) char[n];
00289             #else
00290                 return ::new(alignment, offset,    pName, flags, 0, __FILE__, __LINE__) char[n];
00291             #endif
00292 
00293             #undef pName  // See above for the definition of this.
00294         }
00295 
00296 
00297         inline void allocator::deallocate(void* p, size_t)
00298         {
00299             delete[] (char*)p;
00300         }
00301 
00302 
00303         inline bool operator==(const allocator&, const allocator&)
00304         {
00305             return true; // All allocators are considered equal, as they merely use global new/delete.
00306         }
00307 
00308 
00309         inline bool operator!=(const allocator&, const allocator&)
00310         {
00311             return false; // All allocators are considered equal, as they merely use global new/delete.
00312         }
00313 
00314 
00315     } // namespace eastl
00316 
00317 
00318 #endif // EASTL_USER_DEFINED_ALLOCATOR
00319 
00320 
00321 #ifdef _MSC_VER
00322     #pragma warning(pop)
00323 #endif
00324 
00325 
00326 #endif // Header include guard
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines