ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ManyFastLists.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ManyFastLists.hh
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 /*
27  * G4ManyFastLists.hh
28  *
29  * Created on: 17 nov. 2014
30  * Author: kara
31  */
32 
33 #pragma once
34 
35 #include "G4FastList.hh"
36 #include <set>
37 
38 template<class OBJECT>
40 
41 /*
42  * Roll over many list as if it was one
43  */
44 template<class OBJECT>
45  class G4ManyFastLists : public G4FastList<OBJECT>::Watcher
46  {
47  protected:
50  // TODO use "marked list" insted of vector
51 
52  typedef std::set<typename G4FastList<OBJECT>::Watcher*,
55 
56  public:
58 
61  {
62  }
63 
64  virtual ~G4ManyFastLists() = default;
65 
66  virtual void NotifyDeletingList(G4FastList<OBJECT>* __list)
67  {
68  fAssociatedLists.pop(__list);
69  }
70 
72  {
73  if(fMainListWatchers == nullptr)
74  {
76  }
77 
78  fMainListWatchers->insert(watcher);
79 
81  typename ManyLists::iterator _end = fAssociatedLists.end();
82 
83  for(;it != _end ;++it)
84  {
85  watcher->Watch(*it);
86 // (*it)->AddWatcher(watcher);
87 // (*it)->AddWatcher(watcher);
88  }
89  }
90 
91  inline void Add(G4FastList<OBJECT>* __list)
92  {
93  if (__list == 0) return;
94  fAssociatedLists.push_back(__list); // TODO use the table doubling tech
95  //__list->AddWatcher(this);
96  this->Watch(__list);
97 
98  if(fMainListWatchers == 0) return;
99 
100  typename WatcherSet::iterator it_watcher = fMainListWatchers->begin();
101  typename WatcherSet::iterator end_watcher = fMainListWatchers->end();
102 
103 // G4cout << "G4ManyFastLists::Add -- N watchers ="
104 // << fMainListWatchers->size()
105 // << G4endl;
106 
107  for(;it_watcher != end_watcher ;++it_watcher)
108  {
109 // G4cout << " *** *** *** WATCH --- "
110 // << (*it_watcher)->GetWatcherName()
111 // << G4endl;
112  (*it_watcher)->Watch(__list);
113  }
114 
115  if(__list->empty() == false)
116  {
117  it_watcher = fMainListWatchers->begin();
118 
119  for(;it_watcher != end_watcher ;++it_watcher)
120  {
121  typename G4FastList<OBJECT>::iterator it_obj = __list->begin();
122  for(;it_obj != __list->end() ;++it_obj)
123  {
124 // G4cout << " *** *** *** NOTIFY ADD OBJ --- "
125 // << (*it_watcher)->GetWatcherName()
126 // << G4endl;
127 
128  (*it_watcher)->NotifyAddObject(*it_obj,__list);
129  }
130  }
131  }
132 // else
133 // {
134 // G4cout << "__list->empty() == true" << G4endl;
135 // }
136 
137  /*
138  typename ManyLists::const_iterator __it = fAssociatedLists
139  .begin();
140  typename ManyLists::const_iterator __end = fAssociatedLists
141  .end();
142  for (; __it != __end; __it++)
143  {
144  assert(*__it);
145  }
146  */
147  }
148 
149  inline void Remove(G4FastList<OBJECT>* __list)
150  {
151  if (__list == 0) return;
152  fAssociatedLists.pop(__list); // TODO use the table doubling tech
153  __list->RemoveWatcher(this);
154  this->StopWatching(__list);
155 
156  typename WatcherSet::iterator it = fMainListWatchers->begin();
157  typename WatcherSet::iterator _end = fMainListWatchers->end();
158 
159  for(;it != _end ;++it)
160  {
161  (*it)->StopWatching(__list);
162  }
163 
164 // typename ManyLists::node* __node = __list->GetListNode();
165 // if(__node)
166 // {
167 // __list->SetListNode(0);
168 // delete __node;
169 // }
170  }
171 
172  inline bool Holds(OBJECT* __track) const
173  {
176  for (; __it != __end; __it++)
177  if ((*__it)->Holds(__track)) return true;
178  return false;
179  }
180 
181  inline size_t size() const
182  {
183  size_t __size(0);
184  for (auto __it : fAssociatedLists)
185  {
186  __size += __it->size();
187  }
188  return __size;
189  }
190 
191  inline void RemoveLists()
192  {
193  typename ManyLists::iterator __it = fAssociatedLists.begin();
194  typename ManyLists::iterator __end = fAssociatedLists.end();
195  for (; __it != __end; __it++)
196  {
197  if (*__it)
198  {
199  (*__it)->clear();
200  typename ManyLists::iterator next = __it;
201  next++;
202  Remove(*__it);
203  typename ManyLists::node* __node = __it.GetNode();
204  if(__node)
205  {
206  __node->GetObject()->SetListNode(0);
207  delete __node;
208  }
209 // delete (*__it);
210 
211  __it = next;
212  }
213  }
215  }
216 
217  inline void ClearLists()
218  {
219  typename ManyLists::iterator __it = fAssociatedLists.begin();
220  typename ManyLists::iterator __end = fAssociatedLists.end();
221  for (; __it != __end; __it++)
222  if (*__it) (*__it)->clear();
223  }
224 
225  inline iterator begin();
226  inline iterator end();
227 
228  void pop(OBJECT*);
229  };
230 
231 template<class OBJECT>
233  {
235 
238 
242 
243  private:
244  G4ManyFastLists_iterator() = default;
245 
246  public:
248  typename ManyLists::iterator __it,
249  ManyLists* __lists) :
250  fIterator(__x), fCurrentListIt(__it), fLists(__lists)
251  {
252  }
253 
255  _Self& operator=(const G4ManyFastLists_iterator& __x) = default;
256 
258  {
259  return fIterator.GetNode();
260  }
261 
263  {
264  return *fCurrentListIt;
265  }
266 
267  OBJECT* operator*()
268  {
269  return *fIterator;
270  }
271  const OBJECT* operator*() const
272  {
273  return *fIterator;
274  }
275  OBJECT* operator->()
276  {
277  return *fIterator;
278  }
279  const OBJECT* operator->() const
280  {
281  return *fIterator;
282  }
283 
285  _Self& operator++();
286 
288  {
289  return operator++();
290  }
291 
292  _Self&
294  {
295  if (fLists->empty())
296  {
298  return *this;
299  }
300  if (fCurrentListIt == fLists->begin())
301  {
302  if (fIterator == (*fCurrentListIt)->begin())
303  {
305  return *this;
306  }
307  }
308 
309  if (fCurrentListIt == fLists->end())
310  {
311  fCurrentListIt--;
312  fIterator = (*fCurrentListIt)->end();
313  }
314  else if (fIterator == (*fCurrentListIt)->begin())
315  {
316  fCurrentListIt--;
317  fIterator = (*fCurrentListIt)->end();
318  }
319 
320  fIterator--;
321 
322  while (((*fCurrentListIt)->empty() || fIterator.GetNode() == 0
323  || fIterator.GetNode()->GetObject() == 0)
324  && fCurrentListIt != fLists->begin())
325  {
326  fIterator = (*fCurrentListIt)->begin();
327  fCurrentListIt--;
328  fIterator = (*fCurrentListIt)->end();
329  fIterator--;
330  }
331 
332  if (fIterator.GetNode() == 0 && fCurrentListIt == fLists->begin())
333  {
335  return *this;
336  }
337 
338  return *this;
339  }
340 
342  {
343  return operator--();
344  }
345 
346  G4bool operator==(const _Self& __x) const
347  {
348  return (fIterator == __x.fIterator && fCurrentListIt == __x.fCurrentListIt);
349  } // Fast check
350 
351  G4bool operator!=(const _Self& __x) const
352  {
353  return !(this->operator ==(__x));
354  }
355 
356  protected:
358  {
359  if (fLists->empty() == false)
360  {
361  fIterator = (*(fLists->end()--))->end();
362  }
363  else
364  {
366  }
367  }
368  };
369 
370 template<class OBJECT>
372  {
373  if (fAssociatedLists.empty())
374  {
376  fAssociatedLists.end(),
377  &fAssociatedLists);
378  }
379 
380  typename G4FastList<OBJECT>::iterator trackList_it;
381  int i = 0;
382 
383  typename ManyLists::iterator it = fAssociatedLists.begin();
384  typename ManyLists::iterator _end = fAssociatedLists.end();
385 
386  while (it != _end)
387  {
388  if (*it && (*it)->empty() == false)
389  {
390  trackList_it = (*it)->begin();
391  break;
392  }
393  i++;
394  it++;
395  };
396 
397  if (i == fAssociatedLists.size() || it == _end)
398  {
399  return end();
400  }
401 
402  return G4ManyFastLists_iterator<OBJECT>(trackList_it,
403 // fAssociatedLists.begin(),
404  it,
405  &fAssociatedLists);
406  }
407 
408 template<class OBJECT>
410  {
411  if (fAssociatedLists.empty())
412  {
414  fAssociatedLists.end(),
415  &fAssociatedLists);
416  }
417 
418  return G4ManyFastLists_iterator<OBJECT>((fAssociatedLists.end()--)->end(),
419  fAssociatedLists.end(),
420  &fAssociatedLists);
421  }
422 
423 #include "G4ManyFastLists.icc"