Advertisement
Guest User

Chris Thomasson

a guest
Jun 17th, 2008
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.74 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstddef>
  3. #include <cassert>
  4. #include <new>
  5.  
  6.  
  7. #if ! defined(NDEBUG)
  8. # include <typeinfo>
  9. # define DBG_PRINTF(mp_exp) std::printf mp_exp
  10. #else
  11. # define DBG_PRINTF(mp_exp)
  12. #endif
  13.  
  14.  
  15.  
  16.  
  17. #define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \
  18.   (((std::ptrdiff_t const)(mp_this)) + 1) & (-2) \
  19. ))
  20.  
  21.  
  22. #define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \
  23.   (((std::ptrdiff_t const)(mp_this)) + \
  24.    ALIGN_POW2(mp_align, std::ptrdiff_t const) - 1) \
  25.   & (-ALIGN_POW2(mp_align, std::ptrdiff_t const)) \
  26. ))
  27.  
  28.  
  29.  
  30.  
  31. class stack_region_allocator {
  32.   unsigned char* const m_buf;
  33.   std::size_t const m_size;
  34.   std::size_t m_offset;
  35.   unsigned m_count;
  36.  
  37.  
  38. public:
  39.   stack_region_allocator(
  40.    unsigned char* const buf,
  41.    std::size_t const size
  42.   ) throw(std::bad_alloc)
  43.     : m_buf(buf),
  44.       m_size(size),
  45.       m_offset(0),
  46.       m_count(0) {
  47.     if (! m_buf || ! m_size) {
  48.       assert(m_buf);
  49.       assert(m_size);
  50.       throw std::bad_alloc();
  51.     }
  52.   }
  53.  
  54.   ~stack_region_allocator() throw() {
  55.     assert(! m_offset);
  56.     assert(! m_count);
  57.   }
  58.  
  59.  
  60. public:
  61.   template<typename T>
  62.   T* allocate(
  63.    std::size_t count = 1
  64.   ) throw(std::bad_alloc) {
  65.  
  66.     struct offset_calc {
  67.       char pad;
  68.       T object;
  69.     };
  70.  
  71.     if (! count) {
  72.       count = 1;
  73.     }
  74.  
  75.     DBG_PRINTF(("typename:         %s\n", typeid(T).name()));
  76.     DBG_PRINTF(("object count:     %lu\n",
  77.       (unsigned long)count));
  78.      
  79.     DBG_PRINTF(("object size:      %lu\n",
  80.       (unsigned long)sizeof(T)));
  81.  
  82.     std::size_t const alignment = offsetof(offset_calc, object);
  83.     DBG_PRINTF(("object alignment: %lu\n",
  84.       (unsigned long)alignment));
  85.  
  86.     std::size_t const osize = count * sizeof(T);
  87.     DBG_PRINTF(("allocation size:  %lu\n",
  88.       (unsigned long)osize));
  89.    
  90.     unsigned char* const origin = m_buf + m_offset;
  91.     DBG_PRINTF(("origin buffer:    %p\n", (void*)origin));
  92.    
  93.     unsigned char* const align = (alignment != 1) ?
  94.       ALIGN(origin, unsigned char*, alignment) : origin;
  95.     DBG_PRINTF(("align buffer:     %p\n", (void*)align));
  96.    
  97.     std::ptrdiff_t const diff = align - origin;
  98.     DBG_PRINTF(("difference size:  %d\n", diff));
  99.    
  100.     std::size_t const offset = m_offset + diff;
  101.     DBG_PRINTF(("offset pre-size:  %lu\n",
  102.       (unsigned long)offset));
  103.    
  104.     if (offset + osize > m_size) {
  105.       throw std::bad_alloc();
  106.     }
  107.    
  108.     m_offset = offset + osize;
  109.     DBG_PRINTF(("offset post-size: %lu\n\
  110. --------------------------------------\n",
  111.       (unsigned long)(offset + osize)));
  112.    
  113.     ++m_count;
  114.    
  115.     return reinterpret_cast<T*>(align);
  116.   }
  117.  
  118.   void deallocate(void*) throw() {
  119.     if (! (--m_count)) {
  120.       m_offset = 0;
  121.     }
  122.   }
  123.  
  124.   void reset() throw() {
  125.     m_count = 0;
  126.     m_offset = 0;
  127.   }
  128. };
  129.  
  130.  
  131.  
  132.  
  133. struct foo {
  134.   char c[5];
  135.   short s[2];
  136.   int i[3];
  137.   double d[3];
  138.   long double ld[2];
  139. };
  140.  
  141.  
  142. int main() {
  143.   {
  144.     unsigned char buf[1024 * 8] = { '\0' };
  145.     stack_region_allocator region(buf, sizeof(buf));
  146.     long double* ld1 = region.allocate<long double>();
  147.     char* c = region.allocate<char>(125);
  148.     long double* ld2 = region.allocate<long double>(4);
  149.     double* d = region.allocate<double>(2);
  150.     short* s = region.allocate<short>(7);
  151.     float* f = region.allocate<float>(5);
  152.     foo* _fo = region.allocate<foo>(0);
  153.     foo* _foa = region.allocate<foo>(12);
  154.     char* c2 = region.allocate<char>(13);
  155.     char* c3 = region.allocate<char>(17);
  156.     short* s1 = region.allocate<short>(3);
  157.     foo* _foa1 = region.allocate<foo>(3);
  158.     region.reset();
  159.   }
  160.   std::puts("\n\n\n____________________________________________\
  161. _________________\npress <ENTER> to exit...");
  162.   std::getchar();
  163.   return 0;
  164. }
  165.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement