ScummVM API documentation
pool.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef GAMOS_POOL_H
23 #define GAMOS_POOL_H
24 
25 #include "common/array.h"
26 
27 namespace Gamos {
28 
29 template<class T, int shift = 6>
30 class Pool {
31 public:
32  typedef uint size_type;
34  const size_type _blockSize = (1 << shift);
35  const size_type _blockMask = _blockSize - 1;
36 
37 public:
38 
39  constexpr Pool() : _size(0) {}
40 
41  explicit Pool(size_type count) : _size(count) {
42  alloc(count);
43 
44  size_type n = _size;
45  for (T * blk : _blocks) {
46  for (size_type i = 0; n > 0 && i < _blockSize; i++) {
47  n--;
48  new (blk + i) T();
49  }
50  }
51  }
52 
53  ~Pool() {
54  free();
55  }
56 
57  template<class... TArgs>
58  void emplace_back(TArgs &&...args) {
59  alloc(_size + 1);
60 
61  const size_type blid = _size >> shift;
62  const size_type elid = _size & _blockMask;
63 
64  new (_blocks[blid] + elid)T(Common::forward<TArgs>(args)...);
65 
66  _size++;
67  }
68 
69  void push_back(const T &element) {
70  emplace_back(element);
71  }
72 
73  void push_back(T &&element) {
74  emplace_back(Common::move(element));
75  }
76 
77  T &operator[](size_type idx) {
78  assert(idx < _size);
79 
80  const size_type blid = idx >> shift;
81  const size_type elid = idx & _blockMask;
82 
83  return _blocks[blid][elid];
84  }
85 
86  const T &operator[](size_type idx) const {
87  assert(idx < _size);
88 
89  const size_type blid = idx >> shift;
90  const size_type elid = idx & _blockMask;
91 
92  return _blocks[blid][elid];
93  }
94 
95  size_type size() const {
96  return _size;
97  }
98 
99  bool empty() const {
100  return (_size == 0);
101  }
102 
103  void clear() {
104  free();
105  }
106 
107  T &front() {
108  assert(_size > 0);
109  return _blocks[0][0];
110  }
111 
112  const T &front() const {
113  assert(_size > 0);
114  return _blocks[0][0];
115  }
116 
117  T &back() {
118  assert(_size > 0);
119  return operator[](_size - 1);
120  }
121 
122  const T &back() const {
123  assert(_size > 0);
124  return operator[](_size - 1);
125  }
126 
127 protected:
128  void alloc(size_type count) {
129  size_type blockCount = (count + _blockSize - 1) >> shift;
130  if (_blocks.size() < blockCount) {
131  size_type oldsz = _blocks.size();
132  _blocks.resize(blockCount);
133  for (size_type i = oldsz; i < blockCount; i++) {
134  _blocks[i] = (T*)malloc(sizeof(T) * _blockSize);
135  }
136  }
137  }
138 
139  void free() {
140  size_type n = _size;
141  for (T * blk : _blocks) {
142  for (size_type i = 0; n > 0 && i < _blockSize; i++) {
143  n--;
144  blk[i].~T();
145  }
146  ::free(blk);
147  }
148  _blocks.clear();
149 
150  _size = 0;
151  }
152 
153 protected:
154  Common::Array<T *> _blocks;
155  size_type _size = 0;
156 };
157 
158 }
159 
160 #endif
Definition: array.h:52
Definition: pool.h:30
Definition: blit.h:28
uint size_type
Definition: pool.h:32
size_type size() const
Definition: array.h:316
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
void resize(size_type newSize)
Definition: array.h:412