Skip to content

Instantly share code, notes, and snippets.

@Heisenbug
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Heisenbug/5e2d3d79ce253704239f to your computer and use it in GitHub Desktop.
Save Heisenbug/5e2d3d79ce253704239f to your computer and use it in GitHub Desktop.
Memory Arena and STL Proxy
#pragma once
#include "ArenaProxy.h"
namespace MM
{
template<class MemoryAreaPolicy, class AllocationPolicy, class TrackPolicy, template<class...>class AllocatorType = ArenaProxyAlloc>
class Arena
{
public:
template<typename T> using ContainerAllocator = AllocatorType<Arena,T>;
template <class MemoryAreaPolicy>
explicit Arena( MemoryAreaPolicy memArea)
:m_allocator(memArea.begin(), memArea.end())
{
}
void * Allocate(size_t size, const char *file, int line)
{
void* mem = m_allocator.allocate(size);
m_tracker.OnAllocate(mem, size, file, line);
return mem;
}
void * Allocate(size_t size, size_t alignment, const char *file, int line)
{
void* mem = m_allocator.allocate(size,0,alignment);
m_tracker.OnAllocate(mem, size, file, line);
return mem;
}
void Free(void *ptr)
{
m_allocator.free(ptr);
m_tracker.OnFree(ptr);
}
private:
AllocationPolicy m_allocator;
TrackPolicy m_tracker;
};
}
#pragma once
#include <cassert>
#include <cstddef>
//#include <utility>
namespace MM
{
template<class Arena, typename T>
class ArenaProxyAlloc
{
public:
using size_type = std::size_t;
using value_type = T;
using pointer = T*;
using propagate_on_container_move_assignment = std::true_type;
template <class U> struct rebind { typedef ArenaProxyAlloc<Arena,U> other; };
template <class U>
ArenaProxyAlloc(const ArenaProxyAlloc<Arena,U>& other)
: m_arena(other.m_arena)
{}
ArenaProxyAlloc(const ArenaProxyAlloc& other) : m_arena(other.m_arena)
{
}
ArenaProxyAlloc& operator=(const ArenaProxyAlloc&) = delete;
template <class Arena, typename U> friend class ArenaProxyAlloc;
template <class Arena, class T, class U>
friend
bool
operator==(const ArenaProxyAlloc<Arena, T>& x, const ArenaProxyAlloc<Arena, U>& y);
ArenaProxyAlloc(Arena& a) : m_arena(a){}
T* allocate(size_type size)
{
return static_cast<T*>(m_arena.Allocate(size*sizeof(T), __FILE__, __LINE__));
}
void deallocate(T* ptr, size_type n)
{
m_arena.Free(ptr);
}
private:
Arena& m_arena;
};
template <class Arena, class T, class U>
inline
bool
operator==(const ArenaProxyAlloc<Arena, T>& x, const ArenaProxyAlloc<Arena, U>& y)
{
return &x.m_arena == &y.m_arena;
}
//------------------------------------------- ALIGNED -----------------------------------------
template<class Arena, typename T>
class ArenaProxyAllocAligned
{
public:
using size_type = std::size_t;
using value_type = T;
using pointer = T*;
using propagate_on_container_move_assignment = std::true_type;
template <class U> struct rebind { typedef ArenaProxyAllocAligned<Arena, U> other; };
template <class U>
ArenaProxyAllocAligned(const ArenaProxyAllocAligned<Arena, U>& other)
: m_arena(other.m_arena)
{}
ArenaProxyAllocAligned(const ArenaProxyAllocAligned& other) : m_arena(other.m_arena){}
ArenaProxyAllocAligned& operator=(const ArenaProxyAllocAligned&) = delete;
template <class Arena, typename U> friend class ArenaProxyAllocAligned;
template <class Arena, class T, class U>
friend
bool
operator==(const ArenaProxyAllocAligned<Arena, T>& x, const ArenaProxyAllocAligned<Arena, U>& y);
ArenaProxyAllocAligned(Arena& a) : m_arena(a){}
T* allocate(size_type size)
{
return static_cast<T*>(m_arena.Allocate(size*sizeof(T), std::alignment_of<T>::value ,__FILE__, __LINE__));
}
void deallocate(T* ptr, size_type n)
{
m_arena.Free(ptr);
}
private:
Arena& m_arena;
};
template <class Arena, class T, class U>
inline
bool
operator==(const ArenaProxyAllocAligned<Arena, T>& x, const ArenaProxyAllocAligned<Arena, U>& y)
{
return &x.m_arena == &y.m_arena;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment