lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
crt_heap.h
00001 /*****************************************************/
00002 /* lean Memory                  (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_MEMORY_CRT_HEAP
00006 #define LEAN_MEMORY_CRT_HEAP
00007 
00008 #include "../lean.h"
00009 #include "alignment.h"
00010 
00011 #ifndef LEAN_ASSUME_CRT_ALIGNMENT
00012     // MONITOR: Seems to be guaranteed for MSC & GCC
00013     #ifdef LEAN_64_BIT
00014 
00015 
00016         #define LEAN_ASSUME_CRT_ALIGNMENT 16
00017     #else
00018 
00019 
00020         #define LEAN_ASSUME_CRT_ALIGNMENT 8
00021     #endif
00022 #endif
00023 
00024 namespace lean
00025 {
00026 namespace memory
00027 {
00028 
00030 struct crt_heap
00031 {
00033     typedef size_t size_type;
00035     static const size_type default_alignment = LEAN_ASSUME_CRT_ALIGNMENT;
00036 
00038     static LEAN_INLINE void* allocate(size_type size) { return ::operator new(size); }
00040     static LEAN_INLINE void free(void *memory) { ::operator delete(memory); }
00041 
00043     template <size_t Alignment>
00044     static LEAN_INLINE void* allocate(size_type size)
00045     {
00046         if (Alignment <= default_alignment && check_alignment<Alignment>::valid)
00047             return allocate(size);
00048         else
00049         {
00050             LEAN_STATIC_ASSERT_MSG_ALT(Alignment < static_cast<unsigned char>(-1),
00051                 "Alignment > max unsigned char unsupported.",
00052                 Alignment_bigger_than_max_unsigned_char_unsupported);
00053 
00054             unsigned char *unaligned = reinterpret_cast<unsigned char*>( allocate(size + Alignment) );
00055             unsigned char *aligned = upper_align<Alignment>(unaligned);
00056             aligned[-1] = static_cast<unsigned char>(aligned - unaligned);
00057             return aligned;
00058         }
00059     }
00061     template <size_t Alignment>
00062     static LEAN_INLINE void free(void *memory)
00063     {
00064         if (Alignment <= default_alignment && check_alignment<Alignment>::valid)
00065             free(memory);
00066         else
00067         {
00068             if (memory)
00069                 free(reinterpret_cast<unsigned char*>(memory) - reinterpret_cast<unsigned char*>(memory)[-1]);
00070         }
00071     }
00073     static LEAN_INLINE void free(void *memory, size_t alignment)
00074     {
00075         if (alignment <= default_alignment)
00076             free(memory);
00077         else
00078         {
00079             if (memory)
00080                 free(reinterpret_cast<unsigned char*>(memory) - reinterpret_cast<unsigned char*>(memory)[-1]);
00081         }
00082     }
00083 };
00084 
00085 } // namespace
00086 
00087 using memory::crt_heap;
00088 
00089 } // namespace
00090 
00091 #endif