alloc/arena: argument forwarding for acquire
This commit is contained in:
parent
5601c1e9c4
commit
96769c582e
@ -18,6 +18,8 @@
|
|||||||
#define __UTIL_ALLOC_ARENA_HPP
|
#define __UTIL_ALLOC_ARENA_HPP
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "../memory/deleter.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace util { namespace alloc {
|
namespace util { namespace alloc {
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -25,20 +27,44 @@ namespace util { namespace alloc {
|
|||||||
public:
|
public:
|
||||||
arena (T &store);
|
arena (T &store);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
template <typename U, typename ...Args>
|
||||||
|
U*
|
||||||
|
acquire (Args&&...);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
template <typename U>
|
template <typename U>
|
||||||
U* acquire (void);
|
void
|
||||||
|
release (U*);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
template <typename U>
|
||||||
|
using deleter_t = util::memory::owner_deleter<
|
||||||
|
U,arena<T>,&arena::release
|
||||||
|
>;
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
std::unique_ptr<U> unique (void);
|
using unique_t = std::unique_ptr<U,deleter_t<U>>;
|
||||||
|
|
||||||
|
// the return type must be auto and the implementation must be inline
|
||||||
|
// otherwise we trigger an internal compiler error in gcc-5.2.0
|
||||||
|
// "sorry, unimplemented: mangling offset_ref"
|
||||||
|
template <typename U, typename ...Args>
|
||||||
|
auto
|
||||||
|
unique (Args&& ...args)
|
||||||
|
{
|
||||||
|
return unique_t<U> {
|
||||||
|
acquire<U> (std::forward<Args> (args)...),
|
||||||
|
deleter_t<U> (*this)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
void release (U*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T &m_store;
|
T &m_store;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
||||||
#include "./arena.hpp"
|
#include "./arena.ipp"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,24 +34,18 @@ template <typename U, typename ...Args>
|
|||||||
U*
|
U*
|
||||||
util::alloc::arena<T>::acquire (Args&& ...args)
|
util::alloc::arena<T>::acquire (Args&& ...args)
|
||||||
{
|
{
|
||||||
U *data = m_store.allocate (sizeof (U), alignof (U));
|
U *data = reinterpret_cast<U*> (
|
||||||
|
m_store.allocate (sizeof (U), alignof (U))
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new (data) U (std::forward (args)...);
|
new (data) U (std::forward<Args> (args)...);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_store.deallocate (data, sizeof (U));
|
m_store.deallocate (data, sizeof (U));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return data;
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
template <typename U, typename ...Args>
|
|
||||||
std::unique_ptr<U>
|
|
||||||
util::alloc::arena<T>::unique (Args&& ...args)
|
|
||||||
{
|
|
||||||
return std::unique_ptr<U> (acquire (std::forward (args)...));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -62,7 +56,7 @@ void
|
|||||||
util::alloc::arena<T>::release (U *u)
|
util::alloc::arena<T>::release (U *u)
|
||||||
{
|
{
|
||||||
u->~U ();
|
u->~U ();
|
||||||
m_store.deallocate (u);
|
m_store.deallocate (reinterpret_cast<void*> (u), sizeof (U));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user