/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2015-2018 Danny Robson */ #pragma once #include "../std.hpp" #include "../view.hpp" #include "../pointer.hpp" #include "../buffer/traits.hpp" #include #include namespace cruft::alloc { // allocate progressively across a buffer without concern for deallocation. // deallocation is a noop; the only way to free allocations is via reset. class linear { public: linear (const linear&) = delete; linear& operator= (const linear&) = delete; linear (linear&&) noexcept; linear& operator= (linear&&) noexcept; linear (cruft::view _data); template < typename BufferT, typename = std::enable_if_t< buffer::is_buffer_v > > linear (BufferT &_buffer) : linear (cruft::view (_buffer)) { ; } cruft::view allocate (size_t bytes) { if (m_cursor + bytes > m_end) throw std::bad_alloc (); auto ptr = m_cursor; m_cursor += bytes; return { ptr, bytes }; } cruft::view allocate (size_t bytes, std::size_t alignment) { auto ptr = cruft::align::up (m_cursor, alignment); if (ptr + bytes > m_end) throw std::bad_alloc (); m_cursor = ptr + bytes; return { ptr, bytes }; } void deallocate (void *ptr, std::size_t bytes, std::size_t alignment) { (void)ptr; (void)bytes; (void)alignment; } void deallocate (void *ptr, std::size_t bytes) { return deallocate (ptr, bytes, alignof (std::max_align_t)); } u08* data (void); u08* begin (void); u08* end (void); u08* cursor (void); u08 const* data (void) const; u08 const* begin (void) const; u08 const* end (void) const; u08 const* cursor (void) const; size_t offset (const void*) const; template size_t offset (ValueT const *ptr) const { CHECK_MOD (reinterpret_cast (ptr), sizeof (ValueT)); CHECK_MOD (reinterpret_cast (data ()), sizeof (ValueT)); return ptr - cruft::cast::alignment (data ()); } template size_t offset (cruft::view ptr) const { return offset (ptr.data ()); } void reset (void); size_t capacity (void) const; size_t used (void) const; size_t remain (void) const; protected: // The begin and end iterators should be constant but that interferes // with move operators so we need to leave them mutable. u08 *m_begin; u08 *m_end; u08 *m_cursor; }; }