Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4FastList.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// Author: Mathieu Karamitros
28
29// The code is developed in the framework of the ESA AO7146
30//
31// We would be very happy hearing from you, send us your feedback! :)
32//
33// In order for Geant4-DNA to be maintained and still open-source,
34// article citations are crucial.
35// If you use Geant4-DNA chemistry and you publish papers about your software,
36// in addition to the general paper on Geant4-DNA:
37//
38// Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178
39//
40// we would be very happy if you could please also cite the following
41// reference papers on chemistry:
42//
43// J. Comput. Phys. 274 (2014) 841-882
44// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
45
46#pragma once
47
48#include "globals.hh"
50#include <G4memory.hh>
51#include <vector>
52#include <set>
53//#include "G4ManyFastLists.hh"
54
55template<class OBJECT>
56 class G4FastList;
57template<class OBJECT>
59template<typename OBJECT>
61template<typename OBJECT>
63template<typename OBJECT>
64 class G4ManyFastLists;
65template<typename OBJECT>
67template<class OBJECT>
68 struct sortWatcher;
69
70
71/** Comments :
72 * - A track cannot belong to two different track lists
73 * - Erase a given track is constant complexity
74 * - This development was thought to be used together with G4IT
75 */
76
77#ifndef TYPE_WRAPPER
78#define TYPE_WRAPPER
79template < typename T>
81{
82 using type = T;
83};
84#endif
85
86template<class LIST>
87 struct _ListRef
88 {
91
92//#ifdef WIN32
93// friend typename traits_type::type;
94// friend typename traits_type::type::node;
95// friend typename mli_traits_type::type;
96////#elif defined(__clang__)
97//// friend T;
98//// friend T::node;
99//// friend G4ManyFastLists_iterator<traits_type::type::object>;
100//#else
101// friend class traits_type::type;
102// friend class traits_type::type::node;
103// friend class mli_traits_type::type;
104//#endif
105
106 LIST* fpList;
107
108// protected:
109 inline _ListRef(LIST* __list) :
110 fpList(__list)
111 {
112 ;
113 }
114 };
115
116/**
117 * G4FastListNode is the entity actually stored
118 * by the G4FastList. A G4FastListNode should
119 * belong only to one list. Also, an object
120 * should belong only to one list.
121 */
122
123template<class OBJECT>
125 {
128// typedef type_wrapper<LIST> > ListW;
130// typedef type_wrapper<G4ManyFastLists<typename ObjectW::type> > ManyListsW;
132// typedef type_wrapper<G4ManyFastLists_iterator<typename ObjectW::type> > ManyListsIteratorW;
134
135//#ifdef WIN32
136// friend typename ListW::type;
137// friend typename ManyListsW::type;
138// friend typename ManyListsIteratorW::type;
139////#elif defined(__clang__)
140//// friend T;
141//// friend G4ManyFastLists_iterator<OBJECT>;
142//#else
143// friend class ListW::type;
144// friend class ManyListsW::type;
145// friend struct ManyListsIteratorW::type;
146//#endif
147
148 public:
150
151 OBJECT* GetObject()
152 {
153 return fpObject;
154 }
155
156 const OBJECT* GetObject() const
157 {
158 return fpObject;
159 }
160
162 {
163 return fpNext;
164 }
166 {
167 return fpNext;
168 }
174 {
175 return fpPrevious;
176 }
178 {
179 return fAttachedToList;
180 }
181
182 //protected:
183 /** Default constructor */
184 G4FastListNode(OBJECT* track = nullptr);
185
187 {
188 fpNext = node;
189 }
191 {
192 fpPrevious = node;
193 }
194 void SetAttachedToList(bool flag)
195 {
196 fAttachedToList = flag;
197 }
198
199 void UnHook();
200
202
205 OBJECT* fpObject;
208 };
209
210/**
211 * G4FastList is used by G4TrackHolder to save
212 * G4IT tracks only. Its advantage lies to a fast
213 * search of a track in this list.
214 */
215
216template<class OBJECT>
218 {
219 protected:
221// G4FastListNode<OBJECT> * fpStart;
222// G4FastListNode<OBJECT> * fpFinish;
224
226 // Must be empty and link to the last non-empty node of the list
227 // and to the first non-empty node of the list (begin())
228 // The iterator returned by end() is linked to this empty node
229
230 public:
232 {
233 public:
242
244
249
250 virtual ~Watcher()
251 {
252 auto it = fWatching.begin();
253 auto end = fWatching.end();
254 for(;it!=end;it++)
255 {
256 (*it)->RemoveWatcher(this);
257 }
258 }
259
261 return "";
262 }
263
265 return fPriority;
266 }
267
268 // ===============================
269 // NOTIFICATIONS
271 // used by PriorityList & ManyFastLists
272
273 virtual void NotifyAddObject(OBJECT*, G4FastList<OBJECT>*){;}
274 virtual void NotifyRemoveObject(OBJECT*, G4FastList<OBJECT>*){;}
275// void NotifyEmpty(OBJECT*, G4FastList<OBJECT>*){;}
276
277 // ===============================
278
279 void Watch(G4FastList<OBJECT>* fastList)
280 {
281 fWatching.insert(fastList);
282 fastList->AddWatcher(this);
283 }
284
285 void StopWatching(G4FastList<OBJECT>* fastList, bool removeWatcher = true)
286 {
287 auto it = fWatching.find(fastList);
288 if(it == fWatching.end()) return; //TODO: exception?
289 fWatching.erase(it);
290 if(removeWatcher) fastList->RemoveWatcher(this);
291 }
292
293 protected:
295
296 private:
297 std::set<G4FastList<OBJECT>*> fWatching;
298 };
299
300 template<typename WATCHER_TYPE>
301 class TWatcher : public Watcher
302 {
303 public:
305 virtual ~TWatcher()= default;
307 {
308 return typeid(WATCHER_TYPE).name();
309 }
310 };
311
312 protected:
313 using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*,
317
318 public:
319 using object = OBJECT;
323
326
328 {
329 fpNodeInManyLists = __node;
330 }
331
336
337 void AddWatcher(Watcher* watcher)
338 {
339 fWatchers.insert(watcher);
340 }
341
342 void RemoveWatcher(Watcher* watcher)
343 {
344 auto it = fWatchers.find(watcher);
345 if(it == fWatchers.end()) return; //TODO: exception?
346 fWatchers.erase(it);
347 }
348
349 inline OBJECT* back()
350 {
351// if (fNbObjects != 0) return fpFinish->GetObject();
352 if (fNbObjects != 0) return fBoundary.GetPrevious()->GetObject();
353 return 0;
354 }
355
356 inline G4int size() const
357 {
358 return fNbObjects;
359 }
360
361 inline bool empty() const;
362 iterator insert(iterator /*position*/, OBJECT*);
363
364 inline iterator begin();
365 inline const_iterator begin() const;
366
367 inline iterator end();
368 inline const_iterator end() const;
369 /**
370 * return an iterator that contains an empty node
371 * use for boundary checking only
372 */
373
374 bool Holds(const OBJECT*) const;
375
376 inline void push_front(OBJECT* __track);
377 inline void push_back(OBJECT* __track);
378 OBJECT* pop_back();
379
380 void remove(OBJECT*);
381
382 iterator pop(OBJECT*);
384 iterator pop(iterator __first, iterator __last);
385 iterator erase(OBJECT*);
386 /**
387 * Complexity = constant
388 * By storing the node inside the object, we avoid
389 * searching through all the container.
390 */
391
392 iterator erase(iterator __first, iterator __last);
393 /**
394 * Complexity = linear in size between __first and __last
395 */
396
397 void clear();
399 /**
400 * Complexity = constant
401 */
402
404 static void SetNode(OBJECT* __obj, G4FastListNode<OBJECT>* __node);
405 static G4FastList<OBJECT>* GetList(OBJECT*);
407 static void Pop(OBJECT*);
408
409 protected:
414 void Unflag(G4FastListNode<OBJECT>* __trackListNode);
416 void DeleteObject(OBJECT*);
417
418 void Hook(G4FastListNode<OBJECT>* /*position*/,
419 G4FastListNode<OBJECT>* /*toHook*/);
422
423 private:
424 G4FastList(const G4FastList<OBJECT>& other);
425 G4FastList<OBJECT> & operator=(const G4FastList<OBJECT> &right);
426 G4bool operator==(const G4FastList<OBJECT> &right) const;
427 G4bool operator!=(const G4FastList<OBJECT> &right) const;
428 };
429
430
431template<class OBJECT>
433 {
434 bool operator()(const typename G4FastList<OBJECT>::Watcher* left,
435 const typename G4FastList<OBJECT>::Watcher* right) const
436 {
437 if(left && right)
438 {
439 if(left->GetPriority() != right->GetPriority())
440 {
441 return left->GetPriority() < right->GetPriority();
442 }
443 return left < right;
444 }
445 return false;
446 }
447 };
448
449
450/**
451 * G4FastList_iterator enables to go through
452 * the tracks contained by a list.
453 */
454
455template<typename OBJECT>
457 {
458// friend class G4FastList<OBJECT>;
461
463
464 explicit G4FastList_iterator(_Node* __x) :
465 fpNode(__x)
466 {
467 }
468
470 _Self& operator=(const G4FastList_iterator& right) = default;
471
473 {
474 return fpNode;
475 }
476
477 const _Node* GetNode() const
478 {
479 return fpNode;
480 }
481
482 OBJECT*
484
485 const OBJECT*
486 operator*() const;
487
488 OBJECT*
490
491 const OBJECT*
492 operator->() const;
493
494 _Self&
496 {
497 fpNode = fpNode->GetNext();
498 return *this;
499 }
500
502 {
503 _Self __tmp = *this;
504 fpNode = fpNode->GetNext();
505 return __tmp;
506 }
507
508 _Self&
510 {
512 return *this;
513 }
514
516 {
517 _Self __tmp = *this;
519 return __tmp;
520 }
521
522 G4bool operator==(const _Self& __x) const
523 {
524 return (fpNode == __x.fpNode);
525 }
526
527 G4bool operator!=(const _Self& __x) const
528 {
529 return (fpNode != __x.fpNode);
530 }
531
532// private:
533 // The only member points to the G4FastList_iterator element.
534 _Node* fpNode = nullptr;
535 };
536
537/**
538 * G4FastList_iterator enables to go through
539 * the tracks contained by a list.
540 */
541
542template<typename OBJECT>
544 {
545// friend class G4FastList<OBJECT>;
548
550
551 explicit G4FastList_const_iterator(const _Node* __x) :
552 fpNode(__x)
553 {
554 }
555
557 _Self& operator=(const G4FastList_const_iterator& right) = default;
558
560 fpNode(right.GetNode())
561 {
562 }
563
565 {
566 fpNode = right.GetNode();
567 return *this;
568 }
569
570 const OBJECT*
571 operator*() const
572 {
573 if(fpNode == nullptr) return nullptr;
574 return fpNode->GetObject();
575 }
576
577 const OBJECT*
579 {
580 if(fpNode == 0) return 0;
581 return fpNode->GetObject();
582 }
583
584 _Self&
586 {
587 fpNode = fpNode->GetNext();
588 return *this;
589 }
590
592 {
593 _Self __tmp = *this;
594 fpNode = fpNode->GetNext();
595 return __tmp;
596 }
597
598 _Self&
600 {
602 return *this;
603 }
604
606 {
607 _Self __tmp = *this;
609 return __tmp;
610 }
611
612 G4bool operator==(const _Self& __x) const
613 {
614 return (fpNode == __x.fpNode);
615 }
616
617 G4bool operator!=(const _Self& __x) const
618 {
619 return (fpNode != __x.fpNode);
620 }
621
622// private:
623 // The only member points to the G4FastList_iterator element.
624 const _Node* fpNode = nullptr;
625 };
626
627#include "G4FastList.icc"
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4shared_ptr
Definition G4memory.hh:32
G4FastListNode(OBJECT *track=nullptr)
const G4FastListNode< OBJECT > * GetNext() const
const G4FastListNode< OBJECT > * GetPrevious() const
void SetNext(G4FastListNode< OBJECT > *node)
G4FastListNode< OBJECT > * fpNext
G4FastListNode< OBJECT > * GetPrevious()
const OBJECT * GetObject() const
OBJECT * fpObject
void DetachYourSelf()
G4shared_ptr< _ListRef< G4FastList< OBJECT > > > fListRef
void SetPrevious(G4FastListNode< OBJECT > *node)
G4FastListNode< OBJECT > * fpPrevious
OBJECT * GetObject()
void SetAttachedToList(bool flag)
G4FastListNode< OBJECT > * GetNext()
virtual G4String GetWatcherName()
virtual ~TWatcher()=default
Priority GetPriority() const
virtual void NotifyRemoveObject(OBJECT *, G4FastList< OBJECT > *)
virtual void NotifyAddObject(OBJECT *, G4FastList< OBJECT > *)
virtual G4String GetWatcherName()
void Watch(G4FastList< OBJECT > *fastList)
void StopWatching(G4FastList< OBJECT > *fastList, bool removeWatcher=true)
void NotifyDeletingList(G4FastList< OBJECT > *)
static void Pop(OBJECT *)
static G4FastList< OBJECT > * GetList(G4FastListNode< OBJECT > *__trackListNode)
G4FastListNode< OBJECT > * EraseListNode(OBJECT *)
G4FastListNode< OBJECT > * CreateNode(OBJECT *)
G4int size() const
iterator begin()
void RemoveWatcher(Watcher *watcher)
OBJECT object
static void SetNode(OBJECT *__obj, G4FastListNode< OBJECT > *__node)
void push_front(OBJECT *__track)
void remove(OBJECT *)
G4FastListNode< OBJECT > * Flag(OBJECT *)
bool empty() const
static G4FastList< OBJECT > * GetList(OBJECT *)
void transferTo(G4FastList< OBJECT > *)
iterator end()
void SetListNode(G4FastListNode< G4FastList< OBJECT > > *__node)
OBJECT * pop_back()
G4FastListNode< OBJECT > * Unflag(OBJECT *)
void Unflag(G4FastListNode< OBJECT > *__trackListNode)
void CheckFlag(G4FastListNode< OBJECT > *)
void Unhook(G4FastListNode< OBJECT > *)
void clear()
iterator pop(OBJECT *)
const_iterator begin() const
static G4FastListNode< OBJECT > * __GetNode(OBJECT *)
G4FastListNode< G4FastList< OBJECT > > * GetListNode()
bool Holds(const OBJECT *) const
iterator insert(iterator, OBJECT *)
G4int fNbObjects
iterator pop(G4FastListNode< OBJECT > *)
G4FastListNode< OBJECT > fBoundary
const_iterator end() const
iterator erase(iterator __first, iterator __last)
iterator erase(OBJECT *)
G4shared_ptr< _ListRef< G4FastList< OBJECT > > > fListRef
OBJECT * back()
static G4FastListNode< OBJECT > * GetNode(OBJECT *)
void AddWatcher(Watcher *watcher)
std::set< typename G4FastList< OBJECT >::Watcher *, sortWatcher< OBJECT > > WatcherSet
void DeleteObject(OBJECT *)
void Hook(G4FastListNode< OBJECT > *, G4FastListNode< OBJECT > *)
void push_back(OBJECT *__track)
iterator pop(iterator __first, iterator __last)
WatcherSet fWatchers
G4FastListNode< G4FastList< OBJECT > > * fpNodeInManyLists
_Self & operator=(const G4FastList_const_iterator &right)=default
G4bool operator!=(const _Self &__x) const
G4FastList_const_iterator< OBJECT > _Self
const OBJECT * operator->() const
G4FastList_const_iterator()=default
G4FastList_const_iterator(const G4FastList_iterator< OBJECT > &right)
G4FastList_const_iterator(const _Node *__x)
G4FastList_const_iterator(const G4FastList_const_iterator &right)=default
_Self & operator=(const G4FastList_iterator< OBJECT > &right)
G4bool operator==(const _Self &__x) const
const OBJECT * operator*() const
G4FastList_iterator(_Node *__x)
OBJECT * operator*()
const OBJECT * operator*() const
const OBJECT * operator->() const
G4FastList_iterator()=default
_Self operator--(int)
G4FastList_iterator< OBJECT > _Self
_Self operator++(int)
G4bool operator!=(const _Self &__x) const
G4bool operator==(const _Self &__x) const
const _Node * GetNode() const
_Self & operator=(const G4FastList_iterator &right)=default
G4FastList_iterator(const G4FastList_iterator &right)=default
OBJECT * operator->()
LIST * fpList
_ListRef(LIST *__list)
bool operator()(const typename G4FastList< OBJECT >::Watcher *left, const typename G4FastList< OBJECT >::Watcher *right) const