alloc: duplicate methods with optional args
This commit is contained in:
parent
2c4f6f5526
commit
972b409160
@ -22,11 +22,17 @@
|
||||
namespace util::alloc {
|
||||
template <class parent, class prefix, class suffix>
|
||||
class affix {
|
||||
void* allocate (size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void deallocate (void *ptr, size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void* allocate (size_t bytes);
|
||||
void* allocate (size_t bytes, size_t align);
|
||||
|
||||
void deallocate (void *ptr, size_t bytes);
|
||||
void deallocate (void *ptr, size_t bytes, size_t align);
|
||||
|
||||
void* base (void);
|
||||
const void* base (void) const;
|
||||
|
||||
size_t offset (const void*) const;
|
||||
};
|
||||
}
|
||||
|
||||
#include "./affix.hpp"
|
||||
|
||||
#endif
|
||||
|
@ -38,23 +38,39 @@ namespace util::alloc {
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void
|
||||
auto
|
||||
allocate (size_t bytes, size_t alignment)
|
||||
{
|
||||
CHECK_EQ (alignment, m_alignment);
|
||||
return m_successor.allocate (bytes, m_alignment);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
auto
|
||||
deallocate (void *ptr, size_t bytes)
|
||||
{
|
||||
return m_successor.deallocate (ptr, bytes);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
auto base (void)
|
||||
//---------------------------------------------------------------------
|
||||
auto
|
||||
deallocate (void *ptr, size_t bytes, size_t alignment)
|
||||
{
|
||||
return m_successor.base ();
|
||||
CHECK_EQ (alignment, m_alignment);
|
||||
return m_successor.deallocate (ptr, bytes, m_alignment);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
auto base (void) { return m_successor.base (); }
|
||||
auto base (void) const { return m_successor.base (); }
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
auto
|
||||
offset (const void *ptr)
|
||||
offset (const void *ptr) const
|
||||
{
|
||||
return m_successor.offset (ptr);
|
||||
}
|
||||
|
@ -26,8 +26,7 @@ namespace util::alloc {
|
||||
// allocator interface.
|
||||
class dynamic {
|
||||
public:
|
||||
static constexpr auto DEFAULT_ALIGNMENT = alignof (std::max_align_t);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// disable copying, but allow moving (required for calls to 'make')
|
||||
dynamic (const dynamic&) = delete;
|
||||
dynamic& operator= (const dynamic&) = delete;
|
||||
@ -35,6 +34,7 @@ namespace util::alloc {
|
||||
dynamic (dynamic &&rhs) = default;
|
||||
dynamic& operator= (dynamic&&) = default;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// construct an inner wrapper for type T. used to get around lack of
|
||||
// ambiguous template constructors.
|
||||
template <typename T, typename ...Args>
|
||||
@ -48,38 +48,30 @@ namespace util::alloc {
|
||||
);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// allocation management
|
||||
void*
|
||||
allocate (size_t bytes,
|
||||
size_t alignment = DEFAULT_ALIGNMENT) &
|
||||
{
|
||||
return m_child->allocate (bytes, alignment);
|
||||
}
|
||||
auto allocate (size_t bytes) { return m_child->allocate (bytes); }
|
||||
auto allocate (size_t bytes, size_t alignment) { return m_child->allocate (bytes, alignment); }
|
||||
|
||||
void
|
||||
deallocate (void *ptr,
|
||||
size_t bytes,
|
||||
size_t alignment = DEFAULT_ALIGNMENT)
|
||||
{
|
||||
return m_child->deallocate (ptr, bytes, alignment);
|
||||
}
|
||||
auto deallocate (void *ptr, size_t bytes) { return m_child->deallocate (ptr, bytes); }
|
||||
auto deallocate (void *ptr, size_t bytes, size_t alignment) { return m_child->deallocate (ptr, bytes, alignment); }
|
||||
|
||||
void*
|
||||
base (void)
|
||||
{
|
||||
return m_child->base ();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
auto base (void) { return m_child->base (); }
|
||||
auto base (void) const { return m_child->base (); }
|
||||
|
||||
size_t
|
||||
offset (const void *ptr) const
|
||||
auto offset (const void *ptr) const
|
||||
{ return m_child->offset (ptr); }
|
||||
|
||||
void reset (void) { m_child->reset (); }
|
||||
//---------------------------------------------------------------------
|
||||
auto reset (void) { return m_child->reset (); }
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// capacity queries
|
||||
size_t capacity (void) const { return m_child->capacity (); }
|
||||
size_t used (void) const { return m_child->used (); }
|
||||
size_t remain (void) const { return m_child->remain (); }
|
||||
auto capacity (void) const { return m_child->capacity (); }
|
||||
auto used (void) const { return m_child->used (); }
|
||||
auto remain (void) const { return m_child->remain (); }
|
||||
|
||||
|
||||
private:
|
||||
// Internal base for arbitrary allocator types. Necessary for
|
||||
@ -95,17 +87,15 @@ namespace util::alloc {
|
||||
virtual ~interface () { ; }
|
||||
|
||||
// allocation management
|
||||
virtual void*
|
||||
allocate (size_t bytes,
|
||||
size_t alignment = DEFAULT_ALIGNMENT) = 0;
|
||||
virtual void* allocate (size_t bytes) = 0;
|
||||
virtual void* allocate (size_t bytes, size_t alignment) = 0;
|
||||
|
||||
virtual void
|
||||
deallocate (void *ptr,
|
||||
size_t bytes,
|
||||
size_t alignment = DEFAULT_ALIGNMENT) = 0;
|
||||
virtual void deallocate (void *ptr, size_t bytes) = 0;
|
||||
virtual void deallocate (void *ptr, size_t bytes, size_t alignment) = 0;
|
||||
|
||||
virtual void* base (void) = 0;
|
||||
virtual size_t offset (const void*) const = 0;
|
||||
virtual void* base (void) = 0;
|
||||
virtual const void* base (void) const = 0;
|
||||
virtual size_t offset (const void*) const = 0;
|
||||
|
||||
virtual void reset (void) = 0;
|
||||
|
||||
@ -127,34 +117,35 @@ namespace util::alloc {
|
||||
|
||||
// allocation management
|
||||
void*
|
||||
allocate (size_t bytes,
|
||||
size_t alignment = DEFAULT_ALIGNMENT) override
|
||||
{
|
||||
return m_target.allocate (bytes, alignment);
|
||||
}
|
||||
allocate (size_t bytes) override
|
||||
{ return m_target.allocate (bytes); }
|
||||
|
||||
void*
|
||||
allocate (size_t bytes, size_t alignment) override
|
||||
{ return m_target.allocate (bytes, alignment); }
|
||||
|
||||
void
|
||||
deallocate (void *ptr,
|
||||
size_t bytes,
|
||||
size_t alignment = DEFAULT_ALIGNMENT) override
|
||||
{
|
||||
m_target.deallocate (ptr, bytes, alignment);
|
||||
}
|
||||
deallocate (void *ptr, size_t bytes) override
|
||||
{ m_target.deallocate (ptr, bytes); }
|
||||
|
||||
void *
|
||||
void
|
||||
deallocate (void *ptr, size_t bytes, size_t alignment) override
|
||||
{ m_target.deallocate (ptr, bytes, alignment); }
|
||||
|
||||
const void*
|
||||
base (void) const override
|
||||
{ return m_target.base (); }
|
||||
|
||||
void*
|
||||
base (void) override
|
||||
{
|
||||
return m_target.base ();
|
||||
}
|
||||
{ return m_target.base (); }
|
||||
|
||||
size_t
|
||||
offset (const void *ptr) const override
|
||||
{
|
||||
return m_target.offset (ptr);
|
||||
}
|
||||
{ return m_target.offset (ptr); }
|
||||
|
||||
void reset (void) override
|
||||
{ m_target.reset (); }
|
||||
{ return m_target.reset (); }
|
||||
|
||||
// capacity queries
|
||||
size_t capacity (void) const override { return m_target.capacity (); }
|
||||
|
@ -25,8 +25,11 @@ namespace util::alloc {
|
||||
public:
|
||||
fallback (A&, B&);
|
||||
|
||||
void* allocate (size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void deallocate (void *ptr, size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void* allocate (size_t bytes);
|
||||
void* allocate (size_t bytes, size_t align);
|
||||
|
||||
void deallocate (void *ptr, size_t bytes);
|
||||
void deallocate (void *ptr, size_t bytes, size_t align);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,17 @@
|
||||
|
||||
namespace util::alloc {
|
||||
class affix;
|
||||
class dynamic;
|
||||
class fallback;
|
||||
class linear;
|
||||
class malloc;
|
||||
class null;
|
||||
class stack;
|
||||
|
||||
class dynamic;
|
||||
|
||||
template <typename AllocT>
|
||||
class aligned;
|
||||
|
||||
template <typename T> class arena;
|
||||
template <typename B, typename T> class allocator;
|
||||
}
|
||||
|
@ -37,6 +37,14 @@ linear::linear (void *begin, void *end):
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void*
|
||||
linear::allocate (size_t bytes)
|
||||
{
|
||||
return allocate (bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void*
|
||||
linear::allocate (size_t bytes, size_t alignment)
|
||||
{
|
||||
auto ptr = align (m_cursor, alignment);
|
||||
@ -50,6 +58,14 @@ linear::allocate (size_t bytes, size_t alignment)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
linear::deallocate (void *ptr, size_t bytes)
|
||||
{
|
||||
deallocate (ptr, bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
linear::deallocate (void *ptr, size_t bytes, size_t alignment)
|
||||
@ -68,6 +84,14 @@ linear::base (void)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const void*
|
||||
linear::base (void) const
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
linear::offset (const void *_ptr) const
|
||||
|
@ -31,9 +31,14 @@ namespace util::alloc {
|
||||
|
||||
linear (void *begin, void *end);
|
||||
|
||||
void* allocate (size_t bytes, size_t alignment = alignof (std::max_align_t));
|
||||
void deallocate (void *ptr, size_t bytes, size_t alignment = alignof (std::max_align_t));
|
||||
void* allocate (size_t bytes);
|
||||
void* allocate (size_t bytes, size_t alignment);
|
||||
|
||||
void deallocate (void *ptr, size_t bytes);
|
||||
void deallocate (void *ptr, size_t bytes, size_t alignment);
|
||||
|
||||
void* base (void);
|
||||
const void* base (void) const;
|
||||
size_t offset (const void*) const;
|
||||
|
||||
void reset (void);
|
||||
|
@ -25,15 +25,32 @@ using util::alloc::malloc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void*
|
||||
malloc::allocate (size_t bytes)
|
||||
{
|
||||
return allocate (bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void*
|
||||
malloc::allocate (size_t bytes, size_t align)
|
||||
{
|
||||
// C malloc guarantees maximal alignment
|
||||
CHECK_LE (align, alignof (std::max_align_t));
|
||||
(void)align;
|
||||
|
||||
return ::malloc (bytes);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
malloc::deallocate (void *ptr, size_t bytes)
|
||||
{
|
||||
return deallocate (ptr, bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
malloc::deallocate (void *ptr, size_t bytes, size_t align)
|
||||
|
@ -23,8 +23,11 @@
|
||||
namespace util::alloc {
|
||||
class malloc {
|
||||
public:
|
||||
void* allocate (size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void deallocate (void *ptr, size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void* allocate (size_t bytes);
|
||||
void* allocate (size_t bytes, size_t align);
|
||||
|
||||
void deallocate (void *ptr, size_t bytes);
|
||||
void deallocate (void *ptr, size_t bytes, size_t align);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,14 @@ using util::alloc::null;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void*
|
||||
null::allocate (size_t bytes)
|
||||
{
|
||||
return allocate (bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void*
|
||||
null::allocate (size_t bytes, size_t align)
|
||||
{
|
||||
(void)bytes;
|
||||
@ -35,6 +43,14 @@ null::allocate (size_t bytes, size_t align)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
null::deallocate (void *ptr, size_t bytes)
|
||||
{
|
||||
return deallocate (ptr, bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// calling deallocate with a non-null pointer is undefined, but we may as well
|
||||
// let the application continuing running if we're not in a debug context.
|
||||
@ -48,3 +64,59 @@ null::deallocate (void *ptr, size_t bytes, size_t align)
|
||||
// cast to void* to assist some of the printing machinary in the assertion
|
||||
CHECK_EQ (ptr, (void*)nullptr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void*
|
||||
null::base (void)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const void*
|
||||
null::base (void) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
null::offset (const void *ptr) const
|
||||
{
|
||||
return reinterpret_cast<uintptr_t> (ptr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
null::reset (void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
size_t
|
||||
null::capacity (void) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
null::used (void) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
null::remain (void) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,17 +26,24 @@ namespace util::alloc {
|
||||
// (it is likely to at least assert).
|
||||
class null {
|
||||
public:
|
||||
void* allocate (size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
void deallocate (void *ptr, size_t bytes, size_t align = alignof (std::max_align_t));
|
||||
null () = default;
|
||||
null (const null&) = delete;
|
||||
null& operator= (const null&) = delete;
|
||||
|
||||
constexpr void* base (void) { return nullptr; }
|
||||
constexpr size_t offset (const void*) const { return 0; }
|
||||
void* allocate (size_t bytes);
|
||||
void* allocate (size_t bytes, size_t align);
|
||||
void deallocate (void *ptr, size_t bytes);
|
||||
void deallocate (void *ptr, size_t bytes, size_t align);
|
||||
|
||||
void reset (void) { ; }
|
||||
void* base (void);
|
||||
const void* base (void) const;
|
||||
size_t offset (const void*) const;
|
||||
|
||||
constexpr size_t capacity (void) const { return 0u; }
|
||||
constexpr size_t used (void) const { return 0u; }
|
||||
constexpr size_t remain (void) const { return 0u; }
|
||||
void reset (void);
|
||||
|
||||
size_t capacity (void) const;
|
||||
size_t used (void) const;
|
||||
size_t remain (void) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,14 @@ constexpr auto MIN_ALIGNMENT = sizeof (record::offset_t);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void*
|
||||
stack::allocate (size_t bytes)
|
||||
{
|
||||
return allocate (bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void*
|
||||
stack::allocate (size_t bytes, size_t alignment)
|
||||
{
|
||||
alignment = util::max (MIN_ALIGNMENT, alignment);
|
||||
@ -74,6 +82,14 @@ stack::allocate (size_t bytes, size_t alignment)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
stack::deallocate (void *ptr, size_t bytes)
|
||||
{
|
||||
return deallocate (ptr, bytes, alignof (std::max_align_t));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
stack::deallocate (void *_ptr, size_t bytes, size_t alignment)
|
||||
@ -102,6 +118,14 @@ stack::base (void)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const void*
|
||||
stack::base (void) const
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
stack::offset (const void *_ptr) const
|
||||
|
@ -33,10 +33,14 @@ namespace util::alloc {
|
||||
|
||||
stack (void *begin, void *end);
|
||||
|
||||
//[[gnu::alloc_align (2), gnu::alloc_size (1), gnu::returns_nonnull, gnu::warn_unused_result]
|
||||
void *allocate (size_t bytes, size_t alignment = alignof (std::max_align_t));
|
||||
void deallocate (void *ptr, size_t bytes, size_t alignment = alignof (std::max_align_t));
|
||||
void *allocate (size_t bytes, size_t alignment);
|
||||
void *allocate (size_t bytes);
|
||||
|
||||
void deallocate (void *ptr, size_t bytes);
|
||||
void deallocate (void *ptr, size_t bytes, size_t alignment);
|
||||
|
||||
void* base (void);
|
||||
const void* base (void) const;
|
||||
size_t offset (const void*) const;
|
||||
|
||||
void reset (void);
|
||||
|
Loading…
Reference in New Issue
Block a user