73 lines
1.9 KiB
C++
73 lines
1.9 KiB
C++
/*
|
|
* 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 2021, Danny Robson <danny@nerdcruft.net>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <memory_resource>
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace cruft::alloc {
|
|
/// An unbounded contiguous allocator that operates on chunks, similar to
|
|
/// a deque.
|
|
///
|
|
/// It's useful as a means to keep unknown sized allocations in roughly
|
|
/// the same memory region.
|
|
///
|
|
/// This class models std::pmr::memory_resource.
|
|
class chunked : public std::pmr::memory_resource {
|
|
public:
|
|
static constexpr std::size_t DEFAULT_CHUNK_SIZE = 4096;
|
|
|
|
chunked (chunked const&) = default;
|
|
chunked& operator= (chunked const&) = default;
|
|
|
|
chunked (chunked&&) noexcept = default;
|
|
chunked& operator= (chunked&&) noexcept = default;
|
|
|
|
explicit chunked (std::size_t initial_size);
|
|
chunked (std::size_t initial_size, std::size_t chunk_size);
|
|
~chunked () noexcept;
|
|
|
|
private:
|
|
void* do_allocate (
|
|
std::size_t bytes,
|
|
std::size_t alignment = alignof (std::max_align_t)
|
|
) override;
|
|
|
|
void do_deallocate (
|
|
void *p,
|
|
std::size_t bytes,
|
|
std::size_t alignment = alignof (std::max_align_t)
|
|
) override;
|
|
|
|
bool do_is_equal (memory_resource const&) const noexcept override;
|
|
|
|
std::size_t m_chunk;
|
|
|
|
struct allocation_t {
|
|
std::size_t size;
|
|
allocation_t* next;
|
|
};
|
|
|
|
union node {
|
|
std::byte *data;
|
|
allocation_t *node;
|
|
};
|
|
|
|
struct arena {
|
|
std::byte *head;
|
|
node remain;
|
|
};
|
|
|
|
std::vector<arena> m_data;
|
|
};
|
|
} |