Geant4  10.02
G4ManyFastLists.hh
Go to the documentation of this file.
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 #ifndef G4MANYFASTLISTS_HH_
34 #define G4MANYFASTLISTS_HH_
35 
36 #include "G4FastList.hh"
37 #include <set>
38 
39 template<class OBJECT>
41 
42 /*
43  * Roll over many list as if it was one
44  */
45 template<class OBJECT>
46  class G4ManyFastLists : public G4FastList<OBJECT>::Watcher
47  {
48  protected:
50  ManyLists fAssociatedLists;
51  // TODO use "marked list" insted of vector
52 
53  typedef std::set<typename G4FastList<OBJECT>::Watcher*,
55  WatcherSet* fMainListWatchers;
56 
57  public:
59 
61  fAssociatedLists(), fMainListWatchers(0)
62  {
63  }
64 
65  virtual ~G4ManyFastLists(){;}
66 
67  virtual void NotifyDeletingList(G4FastList<OBJECT>* __list)
68  {
69  fAssociatedLists.pop(__list);
70  }
71 
73  {
74  if(fMainListWatchers == 0)
75  {
76  fMainListWatchers = new WatcherSet();
77  }
78 
79  G4cout << watcher->GetWatcherName() << G4endl;
80 
81  fMainListWatchers->insert(watcher);
82 
83  typename ManyLists::iterator it = fAssociatedLists.begin();
84  typename ManyLists::iterator _end = fAssociatedLists.end();
85 
86  for(;it != _end ;++it)
87  {
88  watcher->Watch(*it);
89 // (*it)->AddWatcher(watcher);
90 // (*it)->AddWatcher(watcher);
91  }
92  }
93 
94  inline void Add(G4FastList<OBJECT>* __list)
95  {
96  if (__list == 0) return;
97  fAssociatedLists.push_back(__list); // TODO use the table doubling tech
98  //__list->AddWatcher(this);
99  this->Watch(__list);
100 
101  if(fMainListWatchers == 0) return;
102 
103  typename WatcherSet::iterator it_watcher = fMainListWatchers->begin();
104  typename WatcherSet::iterator end_watcher = fMainListWatchers->end();
105 
106 // G4cout << "G4ManyFastLists::Add -- N watchers ="
107 // << fMainListWatchers->size()
108 // << G4endl;
109 
110  for(;it_watcher != end_watcher ;++it_watcher)
111  {
112 // G4cout << " *** *** *** WATCH --- "
113 // << (*it_watcher)->GetWatcherName()
114 // << G4endl;
115  (*it_watcher)->Watch(__list);
116  }
117 
118  if(__list->empty() == false)
119  {
120  it_watcher = fMainListWatchers->begin();
121 
122  for(;it_watcher != end_watcher ;++it_watcher)
123  {
124  typename G4FastList<OBJECT>::iterator it_obj = __list->begin();
125  for(;it_obj != __list->end() ;++it_obj)
126  {
127 // G4cout << " *** *** *** NOTIFY ADD OBJ --- "
128 // << (*it_watcher)->GetWatcherName()
129 // << G4endl;
130 
131  (*it_watcher)->NotifyAddObject(*it_obj,__list);
132  }
133  }
134  }
135 // else
136 // {
137 // G4cout << "__list->empty() == true" << G4endl;
138 // }
139 
140  /*
141  typename ManyLists::const_iterator __it = fAssociatedLists
142  .begin();
143  typename ManyLists::const_iterator __end = fAssociatedLists
144  .end();
145  for (; __it != __end; __it++)
146  {
147  assert(*__it);
148  }
149  */
150  }
151 
152  inline void Remove(G4FastList<OBJECT>* __list)
153  {
154  if (__list == 0) return;
155  fAssociatedLists.pop(__list); // TODO use the table doubling tech
156  __list->RemoveWatcher(this);
157  this->StopWatching(__list);
158 
159  typename WatcherSet::iterator it = fMainListWatchers->begin();
160  typename WatcherSet::iterator _end = fMainListWatchers->end();
161 
162  for(;it != _end ;++it)
163  {
164  (*it)->StopWatching(__list);
165  }
166 
167 // typename ManyLists::node* __node = __list->GetListNode();
168 // if(__node)
169 // {
170 // __list->SetListNode(0);
171 // delete __node;
172 // }
173  }
174 
175  inline bool Holds(OBJECT* __track) const
176  {
177  typename ManyLists::const_iterator __it = fAssociatedLists.begin();
178  typename ManyLists::const_iterator __end = fAssociatedLists.end();
179  for (; __it != __end; __it++)
180  if ((*__it)->Holds(__track)) return true;
181  return false;
182  }
183 
184  inline size_t size() const
185  {
186  size_t __size(0);
187  typename ManyLists::const_iterator __it = fAssociatedLists
188  .begin();
189  typename ManyLists::const_iterator __end = fAssociatedLists
190  .end();
191  for (; __it != __end; __it++)
192  {
193  __size += (*__it)->size();
194  }
195  return __size;
196  }
197 
198  inline void RemoveLists()
199  {
200  typename ManyLists::iterator __it = fAssociatedLists.begin();
201  typename ManyLists::iterator __end = fAssociatedLists.end();
202  for (; __it != __end; __it++)
203  {
204  if (*__it)
205  {
206  (*__it)->clear();
207  typename ManyLists::iterator next = __it;
208  next++;
209  Remove(*__it);
210  typename ManyLists::node* __node = __it.GetNode();
211  if(__node)
212  {
213  __node->GetObject()->SetListNode(0);
214  delete __node;
215  }
216 // delete (*__it);
217 
218  __it = next;
219  }
220  }
221  fAssociatedLists.clear();
222  }
223 
224  inline void ClearLists()
225  {
226  typename ManyLists::iterator __it = fAssociatedLists.begin();
227  typename ManyLists::iterator __end = fAssociatedLists.end();
228  for (; __it != __end; __it++)
229  if (*__it) (*__it)->clear();
230  }
231 
232  inline iterator begin();
233  inline iterator end();
234 
235  void pop(OBJECT*);
236  };
237 
238 template<class OBJECT>
240  {
241 // friend class G4ManyFastLists<OBJECT>;
243 
246 
249  ManyLists* fLists;
250 
251  private:
253  fIterator(), fLists(0)
254  {
255  }
256 
257  public:
258 
260  typename ManyLists::iterator __it,
261  ManyLists* __lists) :
262  fIterator(__x), fCurrentListIt(__it), fLists(__lists)
263  {
264  }
265 
267  fIterator(__x.fIterator),
268  fCurrentListIt(__x.fCurrentListIt),
269  fLists(__x.fLists)
270  {
271  }
272 
273  _Node* GetNode()
274  {
275  return fIterator.GetNode();
276  }
277 
279  {
280  return *fCurrentListIt;
281  }
282 
283  OBJECT* operator*()
284  {
285  return *fIterator;
286  }
287  const OBJECT* operator*() const
288  {
289  return *fIterator;
290  }
291  OBJECT* operator->()
292  {
293  return *fIterator;
294  }
295  const OBJECT* operator->() const
296  {
297  return *fIterator;
298  }
299 
300  _Self UpdateToNextValidList();
301  _Self& operator++();
302 
303  _Self operator++(int)
304  {
305  return operator++();
306  }
307 
308  _Self&
310  {
311  if (fLists->empty())
312  {
313  fIterator = G4FastList_iterator<OBJECT>();
314  return *this;
315  }
316  if (fCurrentListIt == fLists->begin())
317  {
318  if (fIterator == (*fCurrentListIt)->begin())
319  {
320  fIterator = G4FastList_iterator<OBJECT>();
321  return *this;
322  }
323  }
324 
325  if (fCurrentListIt == fLists->end())
326  {
327  fCurrentListIt--;
328  fIterator = (*fCurrentListIt)->end();
329  }
330  else if (fIterator == (*fCurrentListIt)->begin())
331  {
332  fCurrentListIt--;
333  fIterator = (*fCurrentListIt)->end();
334  }
335 
336  fIterator--;
337 
338  while (((*fCurrentListIt)->empty() || fIterator.GetNode() == 0
339  || fIterator.GetNode()->GetObject() == 0)
340  && fCurrentListIt != fLists->begin())
341  {
342  fIterator = (*fCurrentListIt)->begin();
343  fCurrentListIt--;
344  fIterator = (*fCurrentListIt)->end();
345  fIterator--;
346  }
347 
348  if (fIterator.GetNode() == 0 && fCurrentListIt == fLists->begin())
349  {
350  fIterator = G4FastList_iterator<OBJECT>();
351  return *this;
352  }
353 
354  return *this;
355  }
356 
357  _Self operator--(int)
358  {
359  return operator--();
360  }
361 
362  bool operator==(const _Self& __x) const
363  {
364  return (fIterator == __x.fIterator && fCurrentListIt == __x.fCurrentListIt);
365  } // Fast check
366 
367  bool operator!=(const _Self& __x) const
368  {
369  return !(this->operator ==(__x));
370  }
371 
372  protected:
374  {
375  if (fLists->empty() == false)
376  {
377  fIterator = (*(fLists->end()--))->end();
378  }
379  else
380  {
381  fIterator = G4FastList_iterator<OBJECT>();
382  }
383  }
384  };
385 
386 template<class OBJECT>
388  {
389  if (fAssociatedLists.empty())
390  {
392  fAssociatedLists.end(),
393  &fAssociatedLists);
394  }
395 
396  typename G4FastList<OBJECT>::iterator trackList_it;
397  int i = 0;
398 
399  typename ManyLists::iterator it = fAssociatedLists.begin();
400  typename ManyLists::iterator _end = fAssociatedLists.end();
401 
402  while (it != _end)
403  {
404  if (*it && (*it)->empty() == false)
405  {
406  trackList_it = (*it)->begin();
407  break;
408  }
409  i++;
410  it++;
411  };
412 
413  if (i == fAssociatedLists.size() || it == _end)
414  {
415  return end();
416  }
417 
418  return G4ManyFastLists_iterator<OBJECT>(trackList_it,
419 // fAssociatedLists.begin(),
420  it,
421  &fAssociatedLists);
422  }
423 
424 template<class OBJECT>
426  {
427  if (fAssociatedLists.empty())
428  {
430  fAssociatedLists.end(),
431  &fAssociatedLists);
432  }
433 
434  return G4ManyFastLists_iterator<OBJECT>((fAssociatedLists.end()--)->end(),
435  fAssociatedLists.end(),
436  &fAssociatedLists);
437  }
438 
439 #include "G4ManyFastLists.icc"
440 #endif /* G4MANYFASTLISTS_HH_ */
G4ManyFastLists_iterator _Self
G4FastList is used by G4TrackHolder to save G4IT tracks only.
Definition: G4FastList.hh:58
void Remove(G4FastList< OBJECT > *__list)
G4FastList_iterator enables to go through the tracks contained by a list.
Definition: G4FastList.hh:62
G4FastList< G4FastList< OBJECT > > ManyLists
G4ManyFastLists< OBJECT > * GetTrackList()
const OBJECT * operator*() const
OBJECT * GetObject()
Definition: G4FastList.hh:154
virtual void NotifyDeletingList(G4FastList< OBJECT > *__list)
iterator pop(OBJECT *)
void Add(G4FastList< OBJECT > *__list)
iterator begin()
G4ManyFastLists_iterator(G4FastList_iterator< OBJECT > __x, typename ManyLists::iterator __it, ManyLists *__lists)
bool empty() const
G4GLOB_DLL std::ostream G4cout
void clear()
Complexity = linear in size between __first and __last.
ManyLists::iterator fCurrentListIt
virtual G4String GetWatcherName()
Definition: G4FastList.hh:263
iterator end()
const OBJECT * operator->() const
G4FastListNode< OBJECT > _Node
G4FastList< G4FastList< OBJECT > > ManyLists
void AddGlobalWatcher(typename G4FastList< OBJECT >::Watcher *watcher)
void RemoveWatcher(Watcher *watcher)
Definition: G4FastList.hh:345
bool operator!=(const _Self &__x) const
void pop(OBJECT *)
G4ManyFastLists_iterator< OBJECT > iterator
void push_back(OBJECT *__track)
bool Holds(OBJECT *__track) const
void SetListNode(G4FastListNode< G4FastList< OBJECT > > *__node)
Definition: G4FastList.hh:330
std::set< typename G4FastList< OBJECT >::Watcher *, sortWatcher< OBJECT > > WatcherSet
size_t size() const
virtual ~G4ManyFastLists()
ManyLists fAssociatedLists
G4ManyFastLists_iterator(const G4ManyFastLists_iterator &__x)
#define G4endl
Definition: G4ios.hh:61
void StopWatching(G4FastList< OBJECT > *fastList, bool removeWatcher=true)
Definition: G4FastList.hh:288
G4FastList_iterator enables to go through the tracks contained by a list.
Definition: G4FastList.hh:64
G4FastList_iterator< OBJECT > fIterator
void Watch(G4FastList< OBJECT > *fastList)
Definition: G4FastList.hh:282
bool operator==(const _Self &__x) const
WatcherSet * fMainListWatchers