-
Notifications
You must be signed in to change notification settings - Fork 1
/
objectPool.h
90 lines (70 loc) · 2.42 KB
/
objectPool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef _OBJHECT_POOL_
#define _OBJHECT_POOL_
#include <vector>
#include <memory>
#include <forward_list>
namespace rgx {
template<typename elemType>
class visitor_ptr;
class _pattern;
template<typename elemType>
class _objectPool {
template<typename Ptr>
using _Convertible = typename std::enable_if<std::is_convertible<Ptr, elemType*>::value>::type;
template<typename T>
friend class visitor_ptr;
friend class _pattern;
public:
_objectPool() : _releasedCount(0) { before_end = _released.before_begin(); }
template<typename actualType, typename... Args, typename = _Convertible<actualType*>>
visitor_ptr<actualType> make_visitor(Args&&... args) {
if (_released.empty()) {
return visitor_ptr<actualType>(back_insert<actualType>(std::forward<Args>(args)...));
} else {
return visitor_ptr<actualType>(front_insert<actualType>(std::forward<Args>(args)...));
}
}
elemType* release(unsigned int index) {
if (index < _pool.size()) {
++_releasedCount;
_released.insert_after(before_end, index);
++before_end;
return _pool[index].release();
}
return nullptr;
}
template<typename actualType, typename = _Convertible<actualType*>>
operator _objectPool<actualType>() {
return _objectPool<actualType>(*this);
}
unsigned int capacity() {
return _pool.size();
}
unsigned int size() {
return capacity() - _releasedCount;
}
private:
std::vector<std::unique_ptr<elemType>> _pool;
std::forward_list<unsigned int> _released;
std::forward_list<unsigned int>::iterator before_end;
unsigned int _releasedCount;
template<typename actualType, typename... Args>
actualType *back_insert(Args&&... args) {
actualType * elem = new actualType(std::forward<Args>(args)...);
_pool.push_back(std::unique_ptr<elemType>(elem));
return elem;
}
template<typename actualType, typename... Args>
actualType *front_insert(Args&&... args) {
unsigned int index = _released.front();
_released.erase_after(_released.before_begin());
actualType* elem = new actualType(std::forward<Args>(args)...);
_pool[index].reset(elem);
return elem;
}
visitor_ptr<elemType> get_visitor(unsigned int index) {
return visitor_ptr<elemType>(_pool[index].get());
}
};
}
#endif