header_utils
Loading...
Searching...
No Matches
pools.h
1
4
5#pragma once
6
7#include <vector>
8#include <memory>
9
10namespace ghassanpl
11{
15
17 template <typename T, size_t BLOCK_SIZE = 1024>
18 struct pool
19 {
20 template <typename... ARGS>
21 T* create(ARGS&&... args)
22 {
23 if (mPointers.empty())
24 {
25 auto& new_block = mBlocks.emplace_back(std::make_unique<mem_proxy[]>(BLOCK_SIZE));
26 for (size_t i = 0; i < BLOCK_SIZE; ++i)
27 mPointers.push_back(&new_block[i]);
28 }
29 auto result = std::construct_at(reinterpret_cast<T*>(mPointers.back()), std::forward<ARGS>(args)...);
30 mPointers.pop_back();
31 return result;
32 }
33
34 void destroy(T* ptr)
35 {
36 std::destroy_at(ptr);
37 mPointers.push_back(std::launder(reinterpret_cast<mem_proxy*>(ptr)));
38 }
39
40 void clear()
41 {
42 mPointers.clear();
43 mBlocks.clear();
44 }
45
46 size_t capacity() const noexcept { return mBlocks.size() * BLOCK_SIZE; }
47 size_t capacity_in_bytes() const noexcept { return capacity() * sizeof(mem_proxy); }
48 size_t free_elements() const noexcept { return mPointers.size(); }
49 size_t allocated_elements() const noexcept { return capacity() - free_elements(); }
50
51 private:
52
54 struct alignas(alignof(T)) mem_proxy { unsigned char mem[sizeof(T)]; };
55 std::vector<mem_proxy*> mPointers;
56 std::vector<std::unique_ptr<mem_proxy[]>> mBlocks;
57 };
58
60 template <typename T, size_t BLOCK_SIZE = 1024>
61 struct thread_local_pool : pool<T, BLOCK_SIZE>
62 {
63
64 static auto& get_pool()
65 {
66 static thread_local thread_local_pool pool{};
67 return pool;
68 }
69
70 struct deleter
71 {
72 void operator()(T* ptr) const
73 {
74 get_pool().destroy(ptr);
75 }
76 };
77
78 using pooled_ptr = std::unique_ptr<T, typename thread_local_pool::deleter>;
79
80 template <typename... ARGS>
81 static pooled_ptr make_pooled(ARGS&&... args)
82 {
83 return pooled_ptr{ thread_local_pool::get_pool().create(std::forward<ARGS>(args)...) };
84 }
85 };
86
88 template <typename T>
89 using pooled_ptr = thread_local_pool<T>::pooled_ptr;
90
92 template <typename T, typename... ARGS>
93 thread_local_pool<T>::pooled_ptr make_pooled(ARGS&&... args)
94 {
95 return pooled_ptr<T>{ thread_local_pool<T>::get_pool().create(std::forward<ARGS>(args)...) };
96 }
97
99}
thread_local_pool< T >::pooled_ptr pooled_ptr
A version of unique_ptr<T> that returns the object to the (thread-local) pool on destruction.
Definition pools.h:89
thread_local_pool< T >::pooled_ptr make_pooled(ARGS &&... args)
Helper to create pooled_ptrs ala make_unique.
Definition pools.h:93
Primary namespace for everything in this library.
Definition align+rec2.h:10
Very simple object pool implementation.
Definition pools.h:19
A pool that can be used in a thread-local fashion.
Definition pools.h:62