Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstddef>
- #include <cassert>
- #include <new>
- #if ! defined(NDEBUG)
- # include <typeinfo>
- # define DBG_PRINTF(mp_exp) std::printf mp_exp
- #else
- # define DBG_PRINTF(mp_exp)
- #endif
- #define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \
- (((std::ptrdiff_t const)(mp_this)) + 1) & (-2) \
- ))
- #define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \
- (((std::ptrdiff_t const)(mp_this)) + \
- ALIGN_POW2(mp_align, std::ptrdiff_t const) - 1) \
- & (-ALIGN_POW2(mp_align, std::ptrdiff_t const)) \
- ))
- class stack_region_allocator {
- unsigned char* const m_buf;
- std::size_t const m_size;
- std::size_t m_offset;
- unsigned m_count;
- public:
- stack_region_allocator(
- unsigned char* const buf,
- std::size_t const size
- ) throw(std::bad_alloc)
- : m_buf(buf),
- m_size(size),
- m_offset(0),
- m_count(0) {
- if (! m_buf || ! m_size) {
- assert(m_buf);
- assert(m_size);
- throw std::bad_alloc();
- }
- }
- ~stack_region_allocator() throw() {
- assert(! m_offset);
- assert(! m_count);
- }
- public:
- template<typename T>
- T* allocate(
- std::size_t count = 1
- ) throw(std::bad_alloc) {
- struct offset_calc {
- char pad;
- T object;
- };
- if (! count) {
- count = 1;
- }
- DBG_PRINTF(("typename: %s\n", typeid(T).name()));
- DBG_PRINTF(("object count: %lu\n",
- (unsigned long)count));
- DBG_PRINTF(("object size: %lu\n",
- (unsigned long)sizeof(T)));
- std::size_t const alignment = offsetof(offset_calc, object);
- DBG_PRINTF(("object alignment: %lu\n",
- (unsigned long)alignment));
- std::size_t const osize = count * sizeof(T);
- DBG_PRINTF(("allocation size: %lu\n",
- (unsigned long)osize));
- unsigned char* const origin = m_buf + m_offset;
- DBG_PRINTF(("origin buffer: %p\n", (void*)origin));
- unsigned char* const align = (alignment != 1) ?
- ALIGN(origin, unsigned char*, alignment) : origin;
- DBG_PRINTF(("align buffer: %p\n", (void*)align));
- std::ptrdiff_t const diff = align - origin;
- DBG_PRINTF(("difference size: %d\n", diff));
- std::size_t const offset = m_offset + diff;
- DBG_PRINTF(("offset pre-size: %lu\n",
- (unsigned long)offset));
- if (offset + osize > m_size) {
- throw std::bad_alloc();
- }
- m_offset = offset + osize;
- DBG_PRINTF(("offset post-size: %lu\n\
- --------------------------------------\n",
- (unsigned long)(offset + osize)));
- ++m_count;
- return reinterpret_cast<T*>(align);
- }
- void deallocate(void*) throw() {
- if (! (--m_count)) {
- m_offset = 0;
- }
- }
- void reset() throw() {
- m_count = 0;
- m_offset = 0;
- }
- };
- struct foo {
- char c[5];
- short s[2];
- int i[3];
- double d[3];
- long double ld[2];
- };
- int main() {
- {
- unsigned char buf[1024 * 8] = { '\0' };
- stack_region_allocator region(buf, sizeof(buf));
- long double* ld1 = region.allocate<long double>();
- char* c = region.allocate<char>(125);
- long double* ld2 = region.allocate<long double>(4);
- double* d = region.allocate<double>(2);
- short* s = region.allocate<short>(7);
- float* f = region.allocate<float>(5);
- foo* _fo = region.allocate<foo>(0);
- foo* _foa = region.allocate<foo>(12);
- char* c2 = region.allocate<char>(13);
- char* c3 = region.allocate<char>(17);
- short* s1 = region.allocate<short>(3);
- foo* _foa1 = region.allocate<foo>(3);
- region.reset();
- }
- std::puts("\n\n\n____________________________________________\
- _________________\npress <ENTER> to exit...");
- std::getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement