BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
fastlist.h
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#ifndef FASTLIST_H
20#define FASTLIST_H
21
22#include <cstdlib>
23#include <iostream>
24#include <list>
25#include <map>
26#include <string>
27#include <vector>
28
29namespace GMAD
30{
41 template<typename T>
42 class FastList {
43
44 public:
46 using FastListIterator = typename std::list<T>::iterator;
47 using FastListConstIterator = typename std::list<T>::const_iterator;
48 using FastMapIterator = typename std::multimap<std::string, FastListIterator>::iterator;
49 using FastMapConstIterator = typename std::multimap<std::string, FastListIterator>::const_iterator;
50 using FastMapIteratorPair = std::pair<FastMapIterator,FastMapIterator>;
51 using FastMapConstIteratorPair = std::pair<FastMapConstIterator,FastMapConstIterator>;
55 template <typename FastListInputIterator>
56 FastListIterator insert(FastListInputIterator position, const T& val);
57 template <typename FastListInputIterator>
58 void insert (FastListConstIterator position, FastListInputIterator first, const FastListInputIterator last);
62 void insert_before(const std::string& name, const T& val);
63
66 void push_back(const T& el, bool unique=false, const std::string& objectName="element");
67
68 inline bool empty() const {return itsList.empty();}
69
71 int size()const;
73 void clear();
75 void erase();
76 FastListConstIterator erase (const FastListConstIterator position);
77 FastListConstIterator erase (const FastListConstIterator first, const FastListConstIterator last);
84 FastListConstIterator begin()const;
85 FastListConstIterator end()const;
87
89 std::vector<T> getVector() const {return std::vector<T>(begin(), end());}
90
94 FastListConstIterator find(std::string name,unsigned int count=1)const;
95 FastListIterator find(std::string name,unsigned int count=1);
98 FastMapIteratorPair equal_range(std::string name);
99 FastMapConstIteratorPair equal_range(std::string name)const;
100
102 void print(int ident=0)const;
103
104 private:
107 typename std::list<T> itsList;
109 std::multimap<std::string, FastListIterator> itsMap;
110 };
111
113 template <typename T>
114 template <typename FastListInputIterator>
115 typename FastList<T>::FastListIterator FastList<T>::insert(FastListInputIterator position, const T& val) {
116 // insert in list
117 FastListIterator it = itsList.insert(position,val);
118 // insert iterator in map with key name
119 itsMap.insert(std::pair<std::string,FastListIterator>(val.name,it));
120 return it;
121 }
122
123 template <typename T>
124 template <typename FastListInputIterator>
125 void FastList<T>::insert(FastListConstIterator position, FastListInputIterator first, const FastListInputIterator last) {
126 for (;first!=last; ++first) {
127 // insert one by one before position
128 FastList<T>::insert(position,*first);
129 }
130 }
131
132 template <typename T>
133 void FastList<T>::insert_before(const std::string& name, const T& val) {
134 FastMapIteratorPair itPair = equal_range(name);
135 if (itPair.first==itPair.second) {
136 std::cerr<<"current list doesn't contain element "<< name << std::endl;
137 exit(1);
138 }
139 // first insert into list and only then into map, otherwise map iterators are invalidated(!)
140 std::vector<FastListIterator> listIterators;
141 for (FastMapIterator it = itPair.first; it != itPair.second; ++it)
142 {
143 FastListIterator listIt = itsList.insert(it->second,val);
144 listIterators.push_back(listIt);
145 }
146 for (FastListIterator it : listIterators) {
147 itsMap.insert(std::pair<std::string,FastListIterator>(val.name,it));
148 }
149 }
150
151 template <typename T>
152 void FastList<T>::push_back(const T& el, bool unique, const std::string& className) {
153 // better to search in map (faster)
154 if (unique && itsMap.find(el.name) != itsMap.end()) {
155 std::cout << "ERROR: " << className << " with name \"" << el.name << "\" already defined." << std::endl;
156 exit(1);
157 }
158 // insert at back of list (insert() instead of push_back() to get iterator for map):
159 FastListIterator it = itsList.insert(end(),el);
160 itsMap.insert(std::pair<std::string,FastListIterator>(el.name,it));
161 }
162
163 template <typename T>
164 int FastList<T>::size()const {
165 return itsList.size();
166 }
167
168 template <typename T>
170 itsList.clear();
171 itsMap.clear();
172 }
173
174 template <typename T>
176 FastListIterator it = begin();
177 for(;it!=end();++it) {
178 delete (*it).lst;
179 }
180 clear();
181 }
182
183 template <typename T>
184 typename FastList<T>::FastListConstIterator FastList<T>::erase(const FastList<T>::FastListConstIterator it) {
185
186 // find entry in map to erase:
187 std::string name = (*it).name;
188 if (itsMap.count(name) == 1) {
189 itsMap.erase(name);
190 }
191 else { // more than one entry with same name
192 FastMapIteratorPair ret = itsMap.equal_range(name);
193 for (FastMapIterator emit = ret.first; emit!=ret.second; ++emit) {
194 if ((*emit).second == it) // valid comparison? if not, how to find correct element?
195 {
196 itsMap.erase(emit);
197 break;
198 }
199 }
200 }
201 return itsList.erase(it);
202 }
203
204 template <typename T>
205 typename FastList<T>::FastListConstIterator FastList<T>::erase(const FastListConstIterator first, const FastListConstIterator last) {
206 FastListConstIterator it=first;
207 while (it!=last) {
208 // erase one by one
209 it = erase(it);
210 }
211 return it;
212 }
213
214 template <typename T>
216 return itsList.begin();
217 }
218
219 template <typename T>
221 return itsList.end();
222 }
223
224 template <typename T>
225 typename FastList<T>::FastListConstIterator FastList<T>::begin()const {
226 return itsList.begin();
227 }
228
229 template <typename T>
230 typename FastList<T>::FastListConstIterator FastList<T>::end()const {
231 return itsList.end();
232 }
233
234 template <typename T>
235 typename FastList<T>::FastMapIteratorPair FastList<T>::equal_range(std::string name) {
236 return itsMap.equal_range(name);
237 }
238
239 template <typename T>
240 typename FastList<T>::FastMapConstIteratorPair FastList<T>::equal_range(std::string name) const {
241 return itsMap.equal_range(name);
242 }
243
244 template <typename T>
245 typename FastList<T>::FastListConstIterator FastList<T>::find(std::string name,unsigned int count)const {
246 if (count==1) {
247 FastMapConstIterator emit = itsMap.find(name);
248 if (emit==itsMap.end()) return itsList.end();
249 return (*emit).second;
250 } else {
251 // if count > 1
252 FastMapConstIteratorPair ret = itsMap.equal_range(name);
253 unsigned int i=1;
254 for (FastMapConstIterator emit = ret.first; emit!=ret.second; ++emit, i++) {
255 if (i==count) {
256 return (*emit).second;
257 }
258 }
259 return itsList.end();
260 }
261 }
262
263 template <typename T>
264 typename FastList<T>::FastListIterator FastList<T>::find(std::string name,unsigned int count) {
265 if (count==1) {
266 FastMapIterator emit = itsMap.find(name);
267 if (emit==itsMap.end()) return itsList.end();
268 // remove constness trick, call erase with empty range
269 FastListIterator it = itsList.erase((*emit).second, (*emit).second);
270 return it;
271 } else {
272 // if count > 1
273 FastMapIteratorPair ret = itsMap.equal_range(name);
274 unsigned int i=1;
275 for (FastMapIterator emit = ret.first; emit!=ret.second; ++emit, i++) {
276 if (i==count) {
277 // remove constness trick, call erase with empty range
278 FastListIterator it = itsList.erase((*emit).second, (*emit).second);
279 return it;
280 }
281 }
282 return itsList.end();
283 }
284 }
285
286 template <typename T>
287 void FastList<T>::print(int ident)const {
288 for(FastListConstIterator it=begin();it!=end();++it)
289 {
290 (*it).print(ident);
291 }
292 }
293}
294
295#endif
List with Efficient Lookup.
Definition: fastlist.h:42
FastListIterator begin()
Definition: fastlist.h:215
FastListConstIterator end() const
Definition: fastlist.h:230
FastListIterator find(std::string name, unsigned int count=1)
Definition: fastlist.h:264
std::vector< T > getVector() const
Get a vector version of this list.
Definition: fastlist.h:89
void print(int ident=0) const
print method
Definition: fastlist.h:287
FastListIterator insert(FastListInputIterator position, const T &val)
template definitions need to be in header
Definition: fastlist.h:115
FastMapIteratorPair equal_range(std::string name)
Definition: fastlist.h:235
void insert(FastListConstIterator position, FastListInputIterator first, const FastListInputIterator last)
template definitions need to be in header
Definition: fastlist.h:125
FastListIterator end()
Definition: fastlist.h:220
FastListConstIterator erase(const FastListConstIterator position)
erase elements
FastListConstIterator erase(const FastListConstIterator first, const FastListConstIterator last)
erase elements
Definition: fastlist.h:205
void insert_before(const std::string &name, const T &val)
Definition: fastlist.h:133
typename std::list< T >::iterator FastListIterator
for ease of reading
Definition: fastlist.h:46
FastListConstIterator begin() const
Definition: fastlist.h:225
void clear()
empty lists
Definition: fastlist.h:169
void erase()
erase elements
Definition: fastlist.h:175
void push_back(const T &el, bool unique=false, const std::string &objectName="element")
Definition: fastlist.h:152
std::list< T > itsList
Definition: fastlist.h:107
bool empty() const
Whether the list is empty.
Definition: fastlist.h:68
FastListConstIterator find(std::string name, unsigned int count=1) const
Definition: fastlist.h:245
std::multimap< std::string, FastListIterator > itsMap
multimap for name lookup
Definition: fastlist.h:109
int size() const
size of list
Definition: fastlist.h:164
Parser namespace for GMAD language. Combination of Geant4 and MAD.