00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4TrackList.hh"
00037 #include "G4IT.hh"
00038 #include "G4Track.hh"
00039
00040 using namespace std;
00041
00042
00043
00044 G4Track*
00045 G4TrackList_iterator::operator*()
00046 { return fpNode->GetTrack(); }
00047
00048 G4Track*
00049 G4TrackList_iterator::operator->()
00050 { return fpNode->GetTrack(); }
00051
00052 const G4Track*
00053 G4TrackList_iterator::operator*() const
00054 { return fpNode->GetTrack(); }
00055
00056 const G4Track*
00057 G4TrackList_iterator::operator->() const
00058 { return fpNode->GetTrack(); }
00059
00060
00061
00062
00063
00064 G4TrackListNode::G4TrackListNode(G4Track* track) :
00065 fpTrack(track),
00066 fpPrevious(0),
00067 fpNext(0)
00068 {
00069 fAttachedToList = false;
00070 }
00071
00072 G4TrackListNode::~G4TrackListNode()
00073 {;}
00074
00075
00076
00077 G4TrackList::G4TrackList() : fBoundary()
00078 {
00079 fListRef = new _ListRef(this);
00080 fpStart = 0;
00081 fpFinish = 0;
00082 fNbTracks = 0 ;
00083 fBoundary.SetPrevious(&fBoundary);
00084 fBoundary.SetNext(&fBoundary);
00085 fBoundary.fAttachedToList = true;
00086 }
00087
00088
00089 G4TrackList::G4TrackList(const G4TrackList& ) : fBoundary()
00090 {
00091
00092
00093 fpFinish = 0;
00094 fpStart = 0;
00095 fNbTracks = 0;
00096 fListRef = 0;
00097 }
00098
00099 G4TrackList& G4TrackList::operator=(const G4TrackList& other)
00100 {
00101
00102 if (this == &other) return *this;
00103
00104 return *this;
00105 }
00106
00107 G4TrackList::~G4TrackList()
00108 {
00109 if( fNbTracks != 0 )
00110 {
00111 G4TrackListNode * __stackedTrack = fpStart;
00112 G4TrackListNode * __nextStackedTrack;
00113
00114
00115 while( __stackedTrack && __stackedTrack != &(fBoundary) )
00116 {
00117 __nextStackedTrack = __stackedTrack->GetNext();
00118 G4Track* __track = __stackedTrack->GetTrack();
00119
00120 delete __stackedTrack;
00121 __stackedTrack = 0;
00122
00123 if(__track)
00124 {
00126 DeleteTrack(__track);
00127 __track = 0;
00129 }
00130
00131 __stackedTrack = __nextStackedTrack;
00132 }
00133 }
00134 fNbTracks = 0;
00135 }
00136
00137 bool G4TrackList::Holds(const G4Track* track) const
00138 {
00139 return (GetIT(track)->GetTrackListNode()->fListRef->fpTrackList == this) ;
00140 }
00141
00142 G4TrackListNode* G4TrackList::Flag(G4Track* __track)
00143 {
00144 G4IT* __iTrack = GetIT(__track);
00145 G4TrackListNode* __trackListNode = __iTrack->GetTrackListNode();
00146
00147 if(__trackListNode != 0)
00148 {
00149
00150 if(__trackListNode->fAttachedToList)
00151 {
00152 G4ExceptionDescription exceptionDescription ;
00153 exceptionDescription << "This track "<< __iTrack->GetName() ;
00154 exceptionDescription << " is already attached to a TrackList ";
00155 G4Exception("G4TrackList::Flag","G4TrackList001",
00156 FatalErrorInArgument,exceptionDescription);
00157 }
00158 }
00159 else
00160 {
00161 __trackListNode = new G4TrackListNode(__track);
00162 __iTrack->SetTrackListNode(__trackListNode);
00163 }
00164
00165 __trackListNode->fAttachedToList = true;
00166 __trackListNode->fListRef = fListRef;
00167 return __trackListNode;
00168 }
00169
00170 G4TrackListNode* G4TrackList::CreateNode(G4Track* __track)
00171 {
00172 G4TrackListNode* __trackListNode = Flag(__track);
00173 return __trackListNode;
00174 }
00175
00176 void G4TrackList::Hook(G4TrackListNode* __position, G4TrackListNode* __toHook)
00177 {
00178 if(fNbTracks == 0)
00179 {
00180
00181
00182 fpStart = __toHook;
00183 fpFinish = __toHook;
00184 __toHook->SetNext(&fBoundary);
00185 __toHook->SetPrevious(&fBoundary);
00186 fBoundary.SetNext(__toHook);
00187 fBoundary.SetPrevious(__toHook);
00188 }
00189 else if( __position == &fBoundary)
00190 {
00191
00192
00193 fpFinish->SetNext( __toHook );
00194 __toHook->SetPrevious( fpFinish );
00195
00196 __toHook->SetNext(&fBoundary);
00197 fBoundary.SetPrevious( __toHook );
00198
00199 fpFinish = __toHook;
00200 }
00201 else if( __position == fpStart )
00202 {
00203
00204
00205 __toHook->SetPrevious( &fBoundary );
00206 fBoundary.SetNext(__toHook);
00207 __toHook->SetNext(fpStart);
00208 fpStart->SetPrevious(__toHook);
00209 fpStart = __toHook;
00210 }
00211 else
00212 {
00213
00214
00215 G4TrackListNode* __previous = __position->GetPrevious();
00216 __toHook->SetPrevious(__previous);
00217 __toHook->SetNext(__position);
00218 __position->SetPrevious(__toHook);
00219 __previous->SetNext(__toHook);
00220 }
00221
00222 fNbTracks++;
00223 }
00224
00225 void G4TrackList::Unhook(G4TrackListNode* __toUnHook)
00226 {
00227 G4TrackListNode* __previous = __toUnHook->GetPrevious();
00228 G4TrackListNode* __next = __toUnHook->GetNext();
00229
00230 __toUnHook->SetPrevious(0);
00231 __toUnHook->SetNext(0);
00232
00233 if( fNbTracks == 1 )
00234 {
00235 fpStart = 0;
00236 fpFinish = 0;
00237 }
00238 else
00239 {
00240 if(__toUnHook == fpFinish)
00241 {
00242 fpFinish = __previous;
00243 }
00244 if(__toUnHook == fpStart)
00245 {
00246 fpStart = __next;
00247 }
00248 }
00249
00250
00251
00252 __next->SetPrevious(__previous);
00253 __previous->SetNext(__next);
00254
00255 fNbTracks--;
00256 }
00257
00258 G4TrackList::iterator G4TrackList::insert(G4TrackList::iterator __position, G4Track* __track)
00259 {
00260 G4TrackListNode* __node = CreateNode(__track);
00261 Hook(__position.fpNode, __node);
00262 return iterator(__node);
00263 }
00264
00265
00266
00267
00268
00269 void G4TrackList::CheckFlag(G4TrackListNode* __trackListNode)
00270 {
00271 if(__trackListNode -> fListRef->fpTrackList != this)
00272 {
00273 G4Track* track = __trackListNode->GetTrack();
00274 G4ExceptionDescription exceptionDescription ;
00275 exceptionDescription
00276 << "The track "<< GetIT(track)->GetName()
00277 << " with trackID " << track->GetTrackID()
00278 << " is not correctly linked to a TrackList."
00279 << G4endl
00280 << "You are probably trying to withdraw this track "
00281 << "from the list but it probably does not belong to "
00282 << "this track list." << G4endl;
00283 G4Exception("G4TrackList::CheckFlag","G4TrackList002",
00284 FatalErrorInArgument,exceptionDescription);
00285 }
00286 }
00287
00288 G4TrackListNode* G4TrackList::Unflag(G4Track* __track)
00289 {
00290 G4IT* __IT = GetIT(__track);
00291 G4TrackListNode* __trackListNode = __IT->GetTrackListNode();
00292
00293 if(__trackListNode == 0)
00294 {
00295 G4ExceptionDescription exceptionDescription ;
00296 exceptionDescription << "This track "<< GetIT(__track)->GetName() ;
00297 exceptionDescription << " was not connected to any trackList ";
00298 G4Exception("G4TrackList::Unflag","G4TrackList003",
00299 FatalErrorInArgument,exceptionDescription);
00300 return 0;
00301 }
00302 CheckFlag(__trackListNode);
00303 __trackListNode->fAttachedToList = false;
00304 __trackListNode->fListRef = 0;
00305 return __trackListNode;
00306 }
00307
00308 G4Track* G4TrackList::pop_back()
00309 {
00310 if( fNbTracks == 0 ) return 0;
00311 G4TrackListNode * __aStackedTrack = fpFinish;
00312 Unhook( __aStackedTrack );
00313 Unflag( __aStackedTrack->GetTrack() );
00314 return __aStackedTrack->GetTrack();
00315 }
00316
00317 G4TrackList::iterator G4TrackList::pop(G4Track* __track)
00318 {
00319 G4TrackListNode* __node = Unflag(__track);
00320 iterator __next(__node->GetNext());
00321 Unhook(__node);
00322 return __next;
00323 }
00324
00325 G4TrackListNode* G4TrackList::EraseTrackListNode(G4Track* __track)
00326 {
00327 G4TrackListNode* __node = Unflag(__track);
00328 GetIT(__track)->SetTrackListNode(0);
00329 G4TrackListNode* __next = __node->GetNext();
00330 Unhook(__node);
00331 delete __node;
00332 return __next;
00333 }
00334
00335 void G4TrackList::DeleteTrack(G4Track* __track)
00336 {
00337 G4Step* __step = const_cast<G4Step*>(__track->GetStep());
00338 if(__step)
00339 {
00340 if(__step->GetfSecondary()) __step->DeleteSecondaryVector();
00341 delete __step;
00342 }
00343 delete __track;
00344 }
00345
00346 G4TrackList::iterator G4TrackList::erase(G4Track* __track)
00347 {
00348 G4TrackListNode* __next_node = EraseTrackListNode(__track);
00350 DeleteTrack(__track);
00351 __track = 0;
00353 iterator __next(__next_node);
00354 return __next;
00355 }
00356
00357 void G4TrackList::remove(G4Track* __track)
00358 {
00359 this->erase(__track);
00360 }
00361
00362 G4TrackList::iterator
00363 G4TrackList::pop(iterator __first, iterator __last)
00364 {
00365 if(fNbTracks == 0) return iterator(&fBoundary);
00366
00367 while (__first != __last)
00368 {
00369 if(__first . fpNode)
00370 __first = pop(*__first);
00371 }
00372 return __last;
00373 }
00374
00375
00376 G4TrackList::iterator
00377 G4TrackList::erase(iterator __first, iterator __last)
00378 {
00379 if(fNbTracks == 0) return iterator(&fBoundary);
00380
00381 while (__first != __last)
00382 {
00383 if(__first . fpNode)
00384 __first = erase(*__first);
00385 }
00386 return __last;
00387 }
00388
00389 void G4TrackList::transferTo(G4TrackList* __destination)
00390 {
00391 if(fNbTracks==0) return;
00392
00393 if(__destination->fNbTracks == 0)
00394 {
00395 __destination->fpStart = this->fpStart ;
00396 __destination->fpFinish = this->fpFinish ;
00397 __destination->fNbTracks = this->fNbTracks;
00398
00399 __destination->fBoundary.SetNext(fpStart);
00400 __destination->fBoundary.SetPrevious(fpFinish);
00401
00402 __destination->fpFinish->SetNext(&__destination->fBoundary);
00403 __destination->fpStart->SetPrevious(&__destination->fBoundary);
00404 }
00405 else
00406 {
00407 this->fpStart->SetPrevious(__destination->fpFinish);
00408 __destination->fpFinish->SetNext(this->fpStart);
00409 __destination->fBoundary.SetPrevious(this->fpFinish);
00410 this->fpFinish->SetNext(&__destination->fBoundary);
00411
00412 __destination->fpFinish = this->fpFinish;
00413 __destination->fNbTracks += this->fNbTracks;
00414 }
00415
00416 fNbTracks = 0;
00417 fpStart = 0;
00418 fpFinish = 0;
00419 this->fBoundary.SetPrevious(&this->fBoundary);
00420 this->fBoundary.SetNext(&this->fBoundary);
00421
00422 fListRef->fpTrackList = __destination;
00423 }