Geant4 Cross Reference |
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> 39 struct G4ManyFastLists_iterator; 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: 48 using ManyLists = G4FastList<G4FastList<OBJECT>>; 49 ManyLists fAssociatedLists; 50 // TODO use "marked list" insted of vector 51 52 using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*, 53 sortWatcher<OBJECT>>; 54 WatcherSet* fMainListWatchers; 55 56 public: 57 using iterator = G4ManyFastLists_iterator<OBJECT>; 58 59 G4ManyFastLists() : G4FastList<OBJECT>::Watcher(), 60 fAssociatedLists(), fMainListWatchers(nullptr) 61 { 62 } 63 64 ~G4ManyFastLists() override = default; 65 66 virtual void NotifyDeletingList(G4FastList<OBJECT>* __list) 67 { 68 fAssociatedLists.pop(__list); 69 } 70 71 void AddGlobalWatcher(typename G4FastList<OBJECT>::Watcher* watcher) 72 { 73 if(fMainListWatchers == nullptr) 74 { 75 fMainListWatchers = new WatcherSet(); 76 } 77 78 fMainListWatchers->insert(watcher); 79 80 typename ManyLists::iterator it = fAssociatedLists.begin(); 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 == nullptr) return; 94 fAssociatedLists.push_back(__list); // TODO use the table doubling tech 95 //__list->AddWatcher(this); 96 this->Watch(__list); 97 98 if(fMainListWatchers == nullptr) return; 99 100 auto it_watcher = fMainListWatchers->begin(); 101 auto 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 == nullptr) return; 152 fAssociatedLists.pop(__list); // TODO use the table doubling tech 153 __list->RemoveWatcher(this); 154 this->StopWatching(__list); 155 156 auto it = fMainListWatchers->begin(); 157 auto _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 { 174 typename ManyLists::const_iterator __it = fAssociatedLists.begin(); 175 typename ManyLists::const_iterator __end = fAssociatedLists.end(); 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(nullptr); 207 delete __node; 208 } 209 // delete (*__it); 210 211 __it = next; 212 } 213 } 214 fAssociatedLists.clear(); 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> 232 struct G4ManyFastLists_iterator 233 { 234 using ManyLists = G4FastList<G4FastList<OBJECT>>; 235 236 using _Self = G4ManyFastLists_iterator; 237 using _Node = G4FastListNode<OBJECT>; 238 239 G4FastList_iterator<OBJECT> fIterator; 240 typename ManyLists::iterator fCurrentListIt; 241 ManyLists* fLists; 242 243 private: 244 G4ManyFastLists_iterator() = default; 245 246 public: 247 explicit G4ManyFastLists_iterator(G4FastList_iterator<OBJECT> __x, 248 typename ManyLists::iterator __it, 249 ManyLists* __lists) : 250 fIterator(__x), fCurrentListIt(__it), fLists(__lists) 251 { 252 } 253 254 G4ManyFastLists_iterator(const G4ManyFastLists_iterator& __x) = default; 255 _Self& operator=(const G4ManyFastLists_iterator& __x) = default; 256 257 _Node* GetNode() 258 { 259 return fIterator.GetNode(); 260 } 261 262 G4FastList<OBJECT>* GetTrackList() 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 284 _Self UpdateToNextValidList(); 285 _Self& operator++(); 286 287 _Self operator++(int) 288 { 289 return operator++(); 290 } 291 292 _Self& 293 operator--() 294 { 295 if (fLists->empty()) 296 { 297 fIterator = G4FastList_iterator<OBJECT>(); 298 return *this; 299 } 300 if (fCurrentListIt == fLists->begin()) 301 { 302 if (fIterator == (*fCurrentListIt)->begin()) 303 { 304 fIterator = G4FastList_iterator<OBJECT>(); 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() == nullptr 323 || fIterator.GetNode()->GetObject() == nullptr) 324 && fCurrentListIt != fLists->begin()) 325 { 326 fIterator = (*fCurrentListIt)->begin(); 327 fCurrentListIt--; 328 fIterator = (*fCurrentListIt)->end(); 329 fIterator--; 330 } 331 332 if (fIterator.GetNode() == nullptr && fCurrentListIt == fLists->begin()) 333 { 334 fIterator = G4FastList_iterator<OBJECT>(); 335 return *this; 336 } 337 338 return *this; 339 } 340 341 _Self operator--(int) 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: 357 void HasReachedEnd() 358 { 359 if (fLists->empty() == false) 360 { 361 fIterator = (*(fLists->end()--))->end(); 362 } 363 else 364 { 365 fIterator = G4FastList_iterator<OBJECT>(); 366 } 367 } 368 }; 369 370 template<class OBJECT> 371 typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::begin() 372 { 373 if (fAssociatedLists.empty()) 374 { 375 return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(), 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> 409 typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::end() 410 { 411 if (fAssociatedLists.empty()) 412 { 413 return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(), 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" 424