From d4ba9fa0618e842ebfbea1261cc32cea55946d61 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 22 May 2019 17:20:24 +1000 Subject: [PATCH] pool: remove typed base queries, tighten alignment tests --- pool.hpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/pool.hpp b/pool.hpp index b16689b3..7dbfb48a 100644 --- a/pool.hpp +++ b/pool.hpp @@ -27,9 +27,9 @@ namespace cruft { protected: union node; - union alignas(node*) node { - std::atomic next; - std::byte data[sizeof(T)]; + union node { + alignas(node*) std::atomic next; + alignas(T) char data[sizeof(T)]; }; static_assert (std::atomic::is_always_lock_free); @@ -148,7 +148,7 @@ namespace cruft { void destroy (size_t idx) { - return destroy (base () + idx); + return destroy (&(*this)[idx]); } @@ -173,21 +173,32 @@ namespace cruft { // Indexing size_t index (T const *ptr) const { - CHECK_LIMIT (ptr, base (), base () + m_capacity); - return ptr - base (); + CHECK_LIMIT (cruft::cast::alignment (ptr), m_head, m_head + m_capacity); + return cruft::cast::alignment (ptr) - m_head; } /// returns the base address of the allocation. /// - // guaranteed to point to the first _possible_ allocated value; - // however it may not be _live_ at any given moment. provided to - // facilitate indexing. - T* base (void) { return reinterpret_cast (m_head); } - T const* base (void) const { return reinterpret_cast (m_head); } + /// guaranteed to point to the first _possible_ allocated value; + /// however it may not be _live_ at any given moment. + /// + /// DO NOT use this pointer for indexing as you will be unable to + /// account for internal node sizes, alignment, or padding. + void * base (void) & { return m_head; } + void const* base (void) const& { return m_head; } - T& operator[] (size_t idx) &; + T& operator[] (size_t idx) & + { + CHECK_LIMIT (idx, 0u, capacity ()); + return *cruft::cast::alignment (&m_head[idx].data[0]); + } - const T& operator[] (size_t idx) const&; + + T const& operator[] (size_t idx) const& + { + CHECK_LIMIT (idx, 0u, capacity ()); + return *cruft::cast::alignment (&m_head[idx].data[0]); + } }; }