From 350dd96b2d52d3ae30fd7db9b4624950f3cc152c Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 22 Jun 2016 19:51:18 +1000 Subject: [PATCH] alloc: add base and offset methods --- alloc/dynamic.hpp | 47 +++++++++++++++++++++++++++++++++---------- alloc/linear.cpp | 19 +++++++++++++++++ alloc/linear.hpp | 2 ++ alloc/null.hpp | 3 +++ alloc/stack.cpp | 19 +++++++++++++++++ alloc/stack.hpp | 2 ++ test/alloc/linear.cpp | 2 ++ test/alloc/stack.cpp | 2 ++ 8 files changed, 85 insertions(+), 11 deletions(-) diff --git a/alloc/dynamic.hpp b/alloc/dynamic.hpp index 1715e2cd..a464ea0a 100644 --- a/alloc/dynamic.hpp +++ b/alloc/dynamic.hpp @@ -64,6 +64,16 @@ namespace util { namespace alloc { 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 (); } // capacity queries @@ -74,15 +84,15 @@ namespace util { namespace alloc { private: // Internal base for arbitrary allocator types. Necessary for // type ellision in super-client classes. - class base { + class interface { public: - base () = default; - base (const base&) = delete; - base (base&&) = delete; - base& operator= (const base&) = delete; - base& operator= (base&&) = delete; + interface () = default; + interface (const interface&) = delete; + interface (interface&&) = delete; + interface& operator= (const interface&) = delete; + interface& operator= (interface&&) = delete; - virtual ~base () { ; } + virtual ~interface () { ; } // allocation management virtual void* @@ -94,6 +104,9 @@ namespace util { namespace alloc { size_t bytes, size_t alignment = DEFAULT_ALIGNMENT) = 0; + virtual void* base (void) = 0; + virtual size_t offset (const void*) const = 0; + virtual void reset (void) = 0; // capacity queries @@ -104,11 +117,11 @@ namespace util { namespace alloc { template - class child final : public base { + class child final : public interface { public: template child (Args &&...args): - base (), + interface (), m_target (std::forward (args)...) { ; } @@ -128,6 +141,18 @@ namespace util { namespace alloc { 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 { m_target.reset (); } @@ -141,11 +166,11 @@ namespace util { namespace alloc { }; - dynamic (std::unique_ptr _child): + dynamic (std::unique_ptr _child): m_child (std::move (_child)) { ; } - std::unique_ptr m_child; + std::unique_ptr m_child; }; } } diff --git a/alloc/linear.cpp b/alloc/linear.cpp index 4755056c..015d97cf 100644 --- a/alloc/linear.cpp +++ b/alloc/linear.cpp @@ -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 (_ptr); + + CHECK_GE (ptr, m_begin); + return ptr - m_begin; +} + + /////////////////////////////////////////////////////////////////////////////// void linear::reset (void) diff --git a/alloc/linear.hpp b/alloc/linear.hpp index 07e07c3b..044e35b5 100644 --- a/alloc/linear.hpp +++ b/alloc/linear.hpp @@ -33,6 +33,8 @@ namespace util { namespace alloc { 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* base (void); + size_t offset (const void*) const; void reset (void); diff --git a/alloc/null.hpp b/alloc/null.hpp index 8d3bd64c..c5e02b36 100644 --- a/alloc/null.hpp +++ b/alloc/null.hpp @@ -29,6 +29,9 @@ namespace util { namespace alloc { 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)); + constexpr void* base (void) { return nullptr; } + constexpr size_t offset (const void*) const { return 0; } + void reset (void) { ; } constexpr size_t capacity (void) const { return 0u; } diff --git a/alloc/stack.cpp b/alloc/stack.cpp index 6d7f6f5c..3298ee58 100644 --- a/alloc/stack.cpp +++ b/alloc/stack.cpp @@ -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 (_ptr); + + CHECK_GE (ptr, m_begin); + return ptr - m_begin; +} + + //----------------------------------------------------------------------------- void stack::reset (void) diff --git a/alloc/stack.hpp b/alloc/stack.hpp index 0cedd583..294868f4 100644 --- a/alloc/stack.hpp +++ b/alloc/stack.hpp @@ -36,6 +36,8 @@ namespace util { namespace alloc { //[[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* base (void); + size_t offset (const void*) const; void reset (void); diff --git a/test/alloc/linear.cpp b/test/alloc/linear.cpp index 338e3437..e8800d70 100644 --- a/test/alloc/linear.cpp +++ b/test/alloc/linear.cpp @@ -12,6 +12,8 @@ main (void) alignas (std::max_align_t) char memory[BUFFER_SIZE]; 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_throw ( diff --git a/test/alloc/stack.cpp b/test/alloc/stack.cpp index 47356516..a52b6b5d 100644 --- a/test/alloc/stack.cpp +++ b/test/alloc/stack.cpp @@ -34,6 +34,8 @@ main (void) 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"); // larger than total allocations should throw