Skip to content

Commit 49edf88

Browse files
committed
Create MemoryPool.tcc
1 parent 4a81695 commit 49edf88

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

C-98/MemoryPool.tcc

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
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 throw()
32+
{
33+
size_t result = reinterpret_cast<size_t>(p);
34+
return ((align - result) % align);
35+
}
36+
37+
38+
39+
template <typename T, size_t BlockSize>
40+
MemoryPool<T, BlockSize>::MemoryPool()
41+
throw()
42+
{
43+
currentBlock_ = 0;
44+
currentSlot_ = 0;
45+
lastSlot_ = 0;
46+
freeSlots_ = 0;
47+
}
48+
49+
50+
51+
template <typename T, size_t BlockSize>
52+
MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool& memoryPool)
53+
throw()
54+
{
55+
MemoryPool();
56+
}
57+
58+
59+
60+
template <typename T, size_t BlockSize>
61+
template<class U>
62+
MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool<U>& memoryPool)
63+
throw()
64+
{
65+
MemoryPool();
66+
}
67+
68+
69+
70+
template <typename T, size_t BlockSize>
71+
MemoryPool<T, BlockSize>::~MemoryPool()
72+
throw()
73+
{
74+
slot_pointer_ curr = currentBlock_;
75+
while (curr != 0) {
76+
slot_pointer_ prev = curr->next;
77+
operator delete(reinterpret_cast<void*>(curr));
78+
curr = prev;
79+
}
80+
}
81+
82+
83+
84+
template <typename T, size_t BlockSize>
85+
inline typename MemoryPool<T, BlockSize>::pointer
86+
MemoryPool<T, BlockSize>::address(reference x)
87+
const throw()
88+
{
89+
return &x;
90+
}
91+
92+
93+
94+
template <typename T, size_t BlockSize>
95+
inline typename MemoryPool<T, BlockSize>::const_pointer
96+
MemoryPool<T, BlockSize>::address(const_reference x)
97+
const throw()
98+
{
99+
return &x;
100+
}
101+
102+
103+
104+
template <typename T, size_t BlockSize>
105+
void
106+
MemoryPool<T, BlockSize>::allocateBlock()
107+
{
108+
// Allocate space for the new block and store a pointer to the previous one
109+
data_pointer_ newBlock = reinterpret_cast<data_pointer_>
110+
(operator new(BlockSize));
111+
reinterpret_cast<slot_pointer_>(newBlock)->next = currentBlock_;
112+
currentBlock_ = reinterpret_cast<slot_pointer_>(newBlock);
113+
// Pad block body to staisfy the alignment requirements for elements
114+
data_pointer_ body = newBlock + sizeof(slot_pointer_);
115+
size_type bodyPadding = padPointer(body, sizeof(slot_type_));
116+
currentSlot_ = reinterpret_cast<slot_pointer_>(body + bodyPadding);
117+
lastSlot_ = reinterpret_cast<slot_pointer_>
118+
(newBlock + BlockSize - sizeof(slot_type_) + 1);
119+
}
120+
121+
122+
123+
template <typename T, size_t BlockSize>
124+
inline typename MemoryPool<T, BlockSize>::pointer
125+
MemoryPool<T, BlockSize>::allocate(size_type, const_pointer)
126+
{
127+
if (freeSlots_ != 0) {
128+
pointer result = reinterpret_cast<pointer>(freeSlots_);
129+
freeSlots_ = freeSlots_->next;
130+
return result;
131+
}
132+
else {
133+
if (currentSlot_ >= lastSlot_)
134+
allocateBlock();
135+
return reinterpret_cast<pointer>(currentSlot_++);
136+
}
137+
}
138+
139+
140+
141+
template <typename T, size_t BlockSize>
142+
inline void
143+
MemoryPool<T, BlockSize>::deallocate(pointer p, size_type)
144+
{
145+
if (p != 0) {
146+
reinterpret_cast<slot_pointer_>(p)->next = freeSlots_;
147+
freeSlots_ = reinterpret_cast<slot_pointer_>(p);
148+
}
149+
}
150+
151+
152+
153+
template <typename T, size_t BlockSize>
154+
inline typename MemoryPool<T, BlockSize>::size_type
155+
MemoryPool<T, BlockSize>::max_size()
156+
const throw()
157+
{
158+
size_type maxBlocks = -1 / BlockSize;
159+
return (BlockSize - sizeof(data_pointer_)) / sizeof(slot_type_) * maxBlocks;
160+
}
161+
162+
163+
164+
template <typename T, size_t BlockSize>
165+
inline void
166+
MemoryPool<T, BlockSize>::construct(pointer p, const_reference val)
167+
{
168+
new (p) value_type (val);
169+
}
170+
171+
172+
173+
template <typename T, size_t BlockSize>
174+
inline void
175+
MemoryPool<T, BlockSize>::destroy(pointer p)
176+
{
177+
p->~value_type();
178+
}
179+
180+
181+
182+
template <typename T, size_t BlockSize>
183+
inline typename MemoryPool<T, BlockSize>::pointer
184+
MemoryPool<T, BlockSize>::newElement(const_reference val)
185+
{
186+
pointer result = allocate();
187+
construct(result, val);
188+
return result;
189+
}
190+
191+
192+
193+
template <typename T, size_t BlockSize>
194+
inline void
195+
MemoryPool<T, BlockSize>::deleteElement(pointer p)
196+
{
197+
if (p != 0) {
198+
p->~value_type();
199+
deallocate(p);
200+
}
201+
}
202+
203+
204+
205+
#endif // MEMORY_BLOCK_TCC

0 commit comments

Comments
 (0)