alloc: add base and offset methods
This commit is contained in:
parent
8e46cc8e3c
commit
350dd96b2d
@ -64,6 +64,16 @@ namespace util { namespace alloc {
|
|||||||
return m_child->deallocate (ptr, bytes, alignment);
|
return m_child->deallocate (ptr, bytes, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
base (void)
|
||||||
|
{
|
||||||
|
return m_child->base ();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
offset (const void *ptr) const
|
||||||
|
{ return m_child->offset (ptr); }
|
||||||
|
|
||||||
void reset (void) { m_child->reset (); }
|
void reset (void) { m_child->reset (); }
|
||||||
|
|
||||||
// capacity queries
|
// capacity queries
|
||||||
@ -74,15 +84,15 @@ namespace util { namespace alloc {
|
|||||||
private:
|
private:
|
||||||
// Internal base for arbitrary allocator types. Necessary for
|
// Internal base for arbitrary allocator types. Necessary for
|
||||||
// type ellision in super-client classes.
|
// type ellision in super-client classes.
|
||||||
class base {
|
class interface {
|
||||||
public:
|
public:
|
||||||
base () = default;
|
interface () = default;
|
||||||
base (const base&) = delete;
|
interface (const interface&) = delete;
|
||||||
base (base&&) = delete;
|
interface (interface&&) = delete;
|
||||||
base& operator= (const base&) = delete;
|
interface& operator= (const interface&) = delete;
|
||||||
base& operator= (base&&) = delete;
|
interface& operator= (interface&&) = delete;
|
||||||
|
|
||||||
virtual ~base () { ; }
|
virtual ~interface () { ; }
|
||||||
|
|
||||||
// allocation management
|
// allocation management
|
||||||
virtual void*
|
virtual void*
|
||||||
@ -94,6 +104,9 @@ namespace util { namespace alloc {
|
|||||||
size_t bytes,
|
size_t bytes,
|
||||||
size_t alignment = DEFAULT_ALIGNMENT) = 0;
|
size_t alignment = DEFAULT_ALIGNMENT) = 0;
|
||||||
|
|
||||||
|
virtual void* base (void) = 0;
|
||||||
|
virtual size_t offset (const void*) const = 0;
|
||||||
|
|
||||||
virtual void reset (void) = 0;
|
virtual void reset (void) = 0;
|
||||||
|
|
||||||
// capacity queries
|
// capacity queries
|
||||||
@ -104,11 +117,11 @@ namespace util { namespace alloc {
|
|||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class child final : public base {
|
class child final : public interface {
|
||||||
public:
|
public:
|
||||||
template <typename ...Args>
|
template <typename ...Args>
|
||||||
child (Args &&...args):
|
child (Args &&...args):
|
||||||
base (),
|
interface (),
|
||||||
m_target (std::forward<Args> (args)...)
|
m_target (std::forward<Args> (args)...)
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
@ -128,6 +141,18 @@ namespace util { namespace alloc {
|
|||||||
m_target.deallocate (ptr, bytes, alignment);
|
m_target.deallocate (ptr, bytes, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
base (void)
|
||||||
|
{
|
||||||
|
return m_target.base ();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
offset (const void *ptr) const
|
||||||
|
{
|
||||||
|
return m_target.offset (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void reset (void) override
|
void reset (void) override
|
||||||
{ m_target.reset (); }
|
{ m_target.reset (); }
|
||||||
|
|
||||||
@ -141,11 +166,11 @@ namespace util { namespace alloc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
dynamic (std::unique_ptr<base> _child):
|
dynamic (std::unique_ptr<interface> _child):
|
||||||
m_child (std::move (_child))
|
m_child (std::move (_child))
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
std::unique_ptr<base> m_child;
|
std::unique_ptr<interface> m_child;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
@ -60,6 +60,25 @@ linear::deallocate (void *ptr, size_t bytes, size_t alignment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void*
|
||||||
|
linear::base (void)
|
||||||
|
{
|
||||||
|
return m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
size_t
|
||||||
|
linear::offset (const void *_ptr) const
|
||||||
|
{
|
||||||
|
auto ptr = reinterpret_cast<const char*> (_ptr);
|
||||||
|
|
||||||
|
CHECK_GE (ptr, m_begin);
|
||||||
|
return ptr - m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
linear::reset (void)
|
linear::reset (void)
|
||||||
|
@ -33,6 +33,8 @@ namespace util { namespace alloc {
|
|||||||
|
|
||||||
void* allocate (size_t bytes, size_t alignment = alignof (std::max_align_t));
|
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 deallocate (void *ptr, size_t bytes, size_t alignment = alignof (std::max_align_t));
|
||||||
|
void* base (void);
|
||||||
|
size_t offset (const void*) const;
|
||||||
|
|
||||||
void reset (void);
|
void reset (void);
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@ namespace util { namespace alloc {
|
|||||||
void* allocate (size_t bytes, size_t align = alignof (std::max_align_t));
|
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 deallocate (void *ptr, size_t bytes, size_t align = alignof (std::max_align_t));
|
||||||
|
|
||||||
|
constexpr void* base (void) { return nullptr; }
|
||||||
|
constexpr size_t offset (const void*) const { return 0; }
|
||||||
|
|
||||||
void reset (void) { ; }
|
void reset (void) { ; }
|
||||||
|
|
||||||
constexpr size_t capacity (void) const { return 0u; }
|
constexpr size_t capacity (void) const { return 0u; }
|
||||||
|
@ -94,6 +94,25 @@ stack::deallocate (void *_ptr, size_t bytes, size_t alignment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void*
|
||||||
|
stack::base (void)
|
||||||
|
{
|
||||||
|
return m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
size_t
|
||||||
|
stack::offset (const void *_ptr) const
|
||||||
|
{
|
||||||
|
auto ptr = reinterpret_cast<const char*> (_ptr);
|
||||||
|
|
||||||
|
CHECK_GE (ptr, m_begin);
|
||||||
|
return ptr - m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
stack::reset (void)
|
stack::reset (void)
|
||||||
|
@ -36,6 +36,8 @@ namespace util { namespace alloc {
|
|||||||
//[[gnu::alloc_align (2), gnu::alloc_size (1), gnu::returns_nonnull, gnu::warn_unused_result]
|
//[[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 *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 deallocate (void *ptr, size_t bytes, size_t alignment = alignof (std::max_align_t));
|
||||||
|
void* base (void);
|
||||||
|
size_t offset (const void*) const;
|
||||||
|
|
||||||
void reset (void);
|
void reset (void);
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ main (void)
|
|||||||
alignas (std::max_align_t) char memory[BUFFER_SIZE];
|
alignas (std::max_align_t) char memory[BUFFER_SIZE];
|
||||||
util::alloc::linear store (std::begin (memory), std::end (memory));
|
util::alloc::linear store (std::begin (memory), std::end (memory));
|
||||||
|
|
||||||
|
tap.expect_eq (store.base (), std::begin (memory), "base pointers match");
|
||||||
|
tap.expect_eq (store.offset (std::begin (memory)), 0u, "base offset is 0");
|
||||||
tap.expect_eq (store.capacity (), BUFFER_SIZE, "bytes capacity matches");
|
tap.expect_eq (store.capacity (), BUFFER_SIZE, "bytes capacity matches");
|
||||||
|
|
||||||
tap.expect_throw<std::bad_alloc> (
|
tap.expect_throw<std::bad_alloc> (
|
||||||
|
@ -34,6 +34,8 @@ main (void)
|
|||||||
|
|
||||||
util::alloc::stack store (memory, memory + BUFFER_AVAILABLE);
|
util::alloc::stack store (memory, memory + BUFFER_AVAILABLE);
|
||||||
|
|
||||||
|
tap.expect_eq (store.base (), std::begin (memory), "base pointers match");
|
||||||
|
tap.expect_eq (store.offset (std::begin (memory)), 0u, "base offset is 0");
|
||||||
tap.expect_eq (store.capacity (), BUFFER_AVAILABLE, "bytes capacity matches");
|
tap.expect_eq (store.capacity (), BUFFER_AVAILABLE, "bytes capacity matches");
|
||||||
|
|
||||||
// larger than total allocations should throw
|
// larger than total allocations should throw
|
||||||
|
Loading…
x
Reference in New Issue
Block a user