Skip to content

Commit 54e8b19

Browse files
committed
Create MemoryPool.tcc
1 parent b057b89 commit 54e8b19

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

MemoryPool.tcc

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/*-
2+
* Copyright (c) 2013 Cosku Acay, http://www.coskuacay.com
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
* IN THE SOFTWARE.
21+
*/
22+
23+
#ifndef MEMORY_BLOCK_TCC
24+
#define MEMORY_BLOCK_TCC
25+
26+
27+
28+
template <typename T, size_t BlockSize>
29+
inline typename MemoryPool<T, BlockSize>::size_type
30+
MemoryPool<T, BlockSize>::padPointer(data_pointer_ p, size_type align)
31+
const noexcept
32+
{
33+
uintptr_t result = reinterpret_cast<uintptr_t>(p);
34+
return ((align - result) % align);
35+
}
36+
37+
38+
39+
template <typename T, size_t BlockSize>
40+
MemoryPool<T, BlockSize>::MemoryPool()
41+
noexcept
42+
{
43+
currentBlock_ = nullptr;
44+
currentSlot_ = nullptr;
45+
lastSlot_ = nullptr;
46+
freeSlots_ = nullptr;
47+
}
48+
49+
50+
51+
template <typename T, size_t BlockSize>
52+
MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool& memoryPool)
53+
noexcept :
54+
MemoryPool()
55+
{}
56+
57+
58+
59+
template <typename T, size_t BlockSize>
60+
MemoryPool<T, BlockSize>::MemoryPool(MemoryPool&& memoryPool)
61+
noexcept
62+
{
63+
currentBlock_ = memoryPool.currentBlock_;
64+
memoryPool.currentBlock_ = nullptr;
65+
currentSlot_ = memoryPool.currentSlot_;
66+
lastSlot_ = memoryPool.lastSlot_;
67+
freeSlots_ = memoryPool.freeSlots;
68+
}
69+
70+
71+
template <typename T, size_t BlockSize>
72+
template<class U>
73+
MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool<U>& memoryPool)
74+
noexcept :
75+
MemoryPool()
76+
{}
77+
78+
79+
80+
template <typename T, size_t BlockSize>
81+
MemoryPool<T, BlockSize>&
82+
MemoryPool<T, BlockSize>::operator=(MemoryPool&& memoryPool)
83+
noexcept
84+
{
85+
if (this != &memoryPool)
86+
{
87+
std::swap(currentBlock_, memoryPool.currentBlock_);
88+
currentSlot_ = memoryPool.currentSlot_;
89+
lastSlot_ = memoryPool.lastSlot_;
90+
freeSlots_ = memoryPool.freeSlots;
91+
}
92+
return *this;
93+
}
94+
95+
96+
97+
template <typename T, size_t BlockSize>
98+
MemoryPool<T, BlockSize>::~MemoryPool()
99+
noexcept
100+
{
101+
slot_pointer_ curr = currentBlock_;
102+
while (curr != nullptr) {
103+
slot_pointer_ prev = curr->next;
104+
operator delete(reinterpret_cast<void*>(curr));
105+
curr = prev;
106+
}
107+
}
108+
109+
110+
111+
template <typename T, size_t BlockSize>
112+
inline typename MemoryPool<T, BlockSize>::pointer
113+
MemoryPool<T, BlockSize>::address(reference x)
114+
const noexcept
115+
{
116+
return &x;
117+
}
118+
119+
120+
121+
template <typename T, size_t BlockSize>
122+
inline typename MemoryPool<T, BlockSize>::const_pointer
123+
MemoryPool<T, BlockSize>::address(const_reference x)
124+
const noexcept
125+
{
126+
return &x;
127+
}
128+
129+
130+
131+
template <typename T, size_t BlockSize>
132+
void
133+
MemoryPool<T, BlockSize>::allocateBlock()
134+
{
135+
// Allocate space for the new block and store a pointer to the previous one
136+
data_pointer_ newBlock = reinterpret_cast<data_pointer_>
137+
(operator new(BlockSize));
138+
reinterpret_cast<slot_pointer_>(newBlock)->next = currentBlock_;
139+
currentBlock_ = reinterpret_cast<slot_pointer_>(newBlock);
140+
// Pad block body to staisfy the alignment requirements for elements
141+
data_pointer_ body = newBlock + sizeof(slot_pointer_);
142+
size_type bodyPadding = padPointer(body, alignof(slot_type_));
143+
currentSlot_ = reinterpret_cast<slot_pointer_>(body + bodyPadding);
144+
lastSlot_ = reinterpret_cast<slot_pointer_>
145+
(newBlock + BlockSize - sizeof(slot_type_) + 1);
146+
}
147+
148+
149+
150+
template <typename T, size_t BlockSize>
151+
inline typename MemoryPool<T, BlockSize>::pointer
152+
MemoryPool<T, BlockSize>::allocate(size_type n, const_pointer hint)
153+
{
154+
if (freeSlots_ != nullptr) {
155+
pointer result = reinterpret_cast<pointer>(freeSlots_);
156+
freeSlots_ = freeSlots_->next;
157+
return result;
158+
}
159+
else {
160+
if (currentSlot_ >= lastSlot_)
161+
allocateBlock();
162+
return reinterpret_cast<pointer>(currentSlot_++);
163+
}
164+
}
165+
166+
167+
168+
template <typename T, size_t BlockSize>
169+
inline void
170+
MemoryPool<T, BlockSize>::deallocate(pointer p, size_type n)
171+
{
172+
if (p != nullptr) {
173+
reinterpret_cast<slot_pointer_>(p)->next = freeSlots_;
174+
freeSlots_ = reinterpret_cast<slot_pointer_>(p);
175+
}
176+
}
177+
178+
179+
180+
template <typename T, size_t BlockSize>
181+
inline typename MemoryPool<T, BlockSize>::size_type
182+
MemoryPool<T, BlockSize>::max_size()
183+
const noexcept
184+
{
185+
size_type maxBlocks = -1 / BlockSize;
186+
return (BlockSize - sizeof(data_pointer_)) / sizeof(slot_type_) * maxBlocks;
187+
}
188+
189+
190+
191+
template <typename T, size_t BlockSize>
192+
template <class U, class... Args>
193+
inline void
194+
MemoryPool<T, BlockSize>::construct(U* p, Args&&... args)
195+
{
196+
new (p) U (std::forward<Args>(args)...);
197+
}
198+
199+
200+
201+
template <typename T, size_t BlockSize>
202+
template <class U>
203+
inline void
204+
MemoryPool<T, BlockSize>::destroy(U* p)
205+
{
206+
p->~U();
207+
}
208+
209+
210+
211+
template <typename T, size_t BlockSize>
212+
template <class... Args>
213+
inline typename MemoryPool<T, BlockSize>::pointer
214+
MemoryPool<T, BlockSize>::newElement(Args&&... args)
215+
{
216+
pointer result = allocate();
217+
construct<value_type>(result, std::forward<Args>(args)...);
218+
return result;
219+
}
220+
221+
222+
223+
template <typename T, size_t BlockSize>
224+
inline void
225+
MemoryPool<T, BlockSize>::deleteElement(pointer p)
226+
{
227+
if (p != nullptr) {
228+
p->~value_type();
229+
deallocate(p);
230+
}
231+
}
232+
233+
234+
235+
#endif // MEMORY_BLOCK_TCC

0 commit comments

Comments
 (0)