Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Geant4/G4ManyFastLists.hh was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /*
0027  * G4ManyFastLists.hh
0028  *
0029  *  Created on: 17 nov. 2014
0030  *      Author: kara
0031  */
0032 
0033 #pragma once
0034 
0035 #include "G4FastList.hh"
0036 #include <set>
0037 
0038 template<class OBJECT>
0039   struct G4ManyFastLists_iterator;
0040 
0041 /*
0042  * Roll over many list as if it was one
0043  */
0044 template<class OBJECT>
0045   class G4ManyFastLists : public G4FastList<OBJECT>::Watcher
0046   {
0047   protected:
0048     using ManyLists = G4FastList<G4FastList<OBJECT>>;
0049     ManyLists fAssociatedLists;
0050     // TODO use "marked list" insted of vector
0051 
0052     using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*,
0053         sortWatcher<OBJECT>>;
0054     WatcherSet* fMainListWatchers;
0055 
0056   public:
0057     using iterator = G4ManyFastLists_iterator<OBJECT>;
0058 
0059     G4ManyFastLists() : G4FastList<OBJECT>::Watcher(),
0060         fAssociatedLists(), fMainListWatchers(nullptr)
0061     {
0062     }
0063 
0064     ~G4ManyFastLists() override = default;
0065 
0066     virtual void NotifyDeletingList(G4FastList<OBJECT>* __list)
0067     {
0068       fAssociatedLists.pop(__list);
0069     }
0070 
0071     void AddGlobalWatcher(typename G4FastList<OBJECT>::Watcher* watcher)
0072     {
0073       if(fMainListWatchers == nullptr)
0074       {
0075         fMainListWatchers = new WatcherSet();
0076       }
0077 
0078       fMainListWatchers->insert(watcher);
0079 
0080       typename ManyLists::iterator it = fAssociatedLists.begin();
0081       typename ManyLists::iterator _end = fAssociatedLists.end();
0082 
0083       for(;it != _end ;++it)
0084       {
0085         watcher->Watch(*it);
0086 //        (*it)->AddWatcher(watcher);
0087 //        (*it)->AddWatcher(watcher);
0088       }
0089     }
0090 
0091     inline void Add(G4FastList<OBJECT>* __list)
0092     {
0093       if (__list == nullptr) return;
0094       fAssociatedLists.push_back(__list); // TODO use the table doubling tech
0095       //__list->AddWatcher(this);
0096       this->Watch(__list);
0097 
0098       if(fMainListWatchers == nullptr) return;
0099 
0100       auto it_watcher = fMainListWatchers->begin();
0101       auto end_watcher = fMainListWatchers->end();
0102 
0103 //      G4cout << "G4ManyFastLists::Add -- N watchers ="
0104 //             << fMainListWatchers->size()
0105 //             << G4endl;
0106 
0107       for(;it_watcher != end_watcher ;++it_watcher)
0108       {
0109 //        G4cout << " *** *** *** WATCH --- "
0110 //                           << (*it_watcher)->GetWatcherName()
0111 //                           << G4endl;
0112         (*it_watcher)->Watch(__list);
0113       }
0114 
0115       if(__list->empty() == false)
0116       {
0117         it_watcher = fMainListWatchers->begin();
0118 
0119         for(;it_watcher != end_watcher ;++it_watcher)
0120         {
0121           typename G4FastList<OBJECT>::iterator it_obj = __list->begin();
0122           for(;it_obj != __list->end() ;++it_obj)
0123           {
0124 //            G4cout << " *** *** *** NOTIFY ADD OBJ --- "
0125 //                   << (*it_watcher)->GetWatcherName()
0126 //                   << G4endl;
0127 
0128             (*it_watcher)->NotifyAddObject(*it_obj,__list);
0129           }
0130         }
0131       }
0132 //      else
0133 //      {
0134 //        G4cout << "__list->empty() == true" << G4endl;
0135 //      }
0136 
0137       /*
0138       typename ManyLists::const_iterator __it = fAssociatedLists
0139           .begin();
0140       typename ManyLists::const_iterator __end = fAssociatedLists
0141           .end();
0142       for (; __it != __end; __it++)
0143       {
0144         assert(*__it);
0145       }
0146       */
0147     }
0148 
0149     inline void Remove(G4FastList<OBJECT>* __list)
0150     {
0151       if (__list == nullptr) return;
0152       fAssociatedLists.pop(__list); // TODO use the table doubling tech
0153       __list->RemoveWatcher(this);
0154       this->StopWatching(__list);
0155 
0156       auto it = fMainListWatchers->begin();
0157       auto _end = fMainListWatchers->end();
0158 
0159       for(;it != _end ;++it)
0160       {
0161         (*it)->StopWatching(__list);
0162       }
0163 
0164 //      typename ManyLists::node* __node = __list->GetListNode();
0165 //      if(__node)
0166 //      {
0167 //        __list->SetListNode(0);
0168 //        delete __node;
0169 //      }
0170     }
0171 
0172     inline bool Holds(OBJECT* __track) const
0173     {
0174       typename ManyLists::const_iterator __it = fAssociatedLists.begin();
0175       typename ManyLists::const_iterator __end = fAssociatedLists.end();
0176       for (; __it != __end; __it++)
0177         if ((*__it)->Holds(__track)) return true;
0178       return false;
0179     }
0180 
0181     inline size_t size() const
0182     {
0183       size_t __size(0);
0184       for (auto __it : fAssociatedLists)
0185       {
0186         __size += __it->size();
0187       }
0188       return __size;
0189     }
0190 
0191     inline void RemoveLists()
0192     {
0193       typename ManyLists::iterator __it = fAssociatedLists.begin();
0194       typename ManyLists::iterator __end = fAssociatedLists.end();
0195       for (; __it != __end; __it++)
0196       {
0197         if (*__it)
0198         {
0199           (*__it)->clear();
0200           typename ManyLists::iterator next = __it;
0201           next++;
0202           Remove(*__it);
0203           typename ManyLists::node* __node = __it.GetNode();
0204           if(__node)
0205           {
0206             __node->GetObject()->SetListNode(nullptr);
0207             delete __node;
0208           }
0209 //          delete (*__it);
0210 
0211           __it = next;
0212         }
0213       }
0214       fAssociatedLists.clear();
0215     }
0216 
0217     inline void ClearLists()
0218     {
0219       typename ManyLists::iterator __it = fAssociatedLists.begin();
0220       typename ManyLists::iterator __end = fAssociatedLists.end();
0221       for (; __it != __end; __it++)
0222         if (*__it) (*__it)->clear();
0223     }
0224 
0225     inline iterator begin();
0226     inline iterator end();
0227 
0228     void pop(OBJECT*);
0229   };
0230 
0231 template<class OBJECT>
0232   struct G4ManyFastLists_iterator
0233   {
0234     using ManyLists = G4FastList<G4FastList<OBJECT>>;
0235 
0236     using _Self = G4ManyFastLists_iterator;
0237     using _Node = G4FastListNode<OBJECT>;
0238 
0239     G4FastList_iterator<OBJECT> fIterator;
0240     typename ManyLists::iterator fCurrentListIt;
0241     ManyLists* fLists;
0242 
0243   private:
0244     G4ManyFastLists_iterator() = default;
0245 
0246   public:
0247     explicit G4ManyFastLists_iterator(G4FastList_iterator<OBJECT> __x,
0248                                       typename ManyLists::iterator __it,
0249                                       ManyLists* __lists) :
0250         fIterator(__x), fCurrentListIt(__it), fLists(__lists)
0251     {
0252     }
0253 
0254     G4ManyFastLists_iterator(const G4ManyFastLists_iterator& __x) = default;
0255     _Self& operator=(const G4ManyFastLists_iterator& __x) = default;
0256 
0257     _Node* GetNode()
0258     {
0259       return fIterator.GetNode();
0260     }
0261 
0262     G4FastList<OBJECT>* GetTrackList()
0263     {
0264       return *fCurrentListIt;
0265     }
0266 
0267     OBJECT* operator*()
0268     {
0269       return *fIterator;
0270     }
0271     const OBJECT* operator*() const
0272     {
0273       return *fIterator;
0274     }
0275     OBJECT* operator->()
0276     {
0277       return *fIterator;
0278     }
0279     const OBJECT* operator->() const
0280     {
0281       return *fIterator;
0282     }
0283 
0284     _Self UpdateToNextValidList();
0285     _Self& operator++();
0286 
0287     _Self operator++(int)
0288     {
0289       return operator++();
0290     }
0291 
0292     _Self&
0293     operator--()
0294     {
0295       if (fLists->empty())
0296       {
0297         fIterator = G4FastList_iterator<OBJECT>();
0298         return *this;
0299       }
0300       if (fCurrentListIt == fLists->begin())
0301       {
0302         if (fIterator == (*fCurrentListIt)->begin())
0303         {
0304           fIterator = G4FastList_iterator<OBJECT>();
0305           return *this;
0306         }
0307       }
0308 
0309       if (fCurrentListIt == fLists->end())
0310       {
0311         fCurrentListIt--;
0312         fIterator = (*fCurrentListIt)->end();
0313       }
0314       else if (fIterator == (*fCurrentListIt)->begin())
0315       {
0316         fCurrentListIt--;
0317         fIterator = (*fCurrentListIt)->end();
0318       }
0319 
0320       fIterator--;
0321 
0322       while (((*fCurrentListIt)->empty() || fIterator.GetNode() == nullptr
0323               || fIterator.GetNode()->GetObject() == nullptr)
0324              && fCurrentListIt != fLists->begin())
0325       {
0326         fIterator = (*fCurrentListIt)->begin();
0327         fCurrentListIt--;
0328         fIterator = (*fCurrentListIt)->end();
0329         fIterator--;
0330       }
0331 
0332       if (fIterator.GetNode() == nullptr && fCurrentListIt == fLists->begin())
0333       {
0334         fIterator = G4FastList_iterator<OBJECT>();
0335         return *this;
0336       }
0337 
0338       return *this;
0339     }
0340 
0341     _Self operator--(int)
0342     {
0343       return operator--();
0344     }
0345 
0346     G4bool operator==(const _Self& __x) const
0347     {
0348       return (fIterator == __x.fIterator && fCurrentListIt == __x.fCurrentListIt);
0349     } // Fast check
0350 
0351     G4bool operator!=(const _Self& __x) const
0352     {
0353       return !(this->operator ==(__x));
0354     }
0355 
0356   protected:
0357     void HasReachedEnd()
0358     {
0359       if (fLists->empty() == false)
0360       {
0361         fIterator = (*(fLists->end()--))->end();
0362       }
0363       else
0364       {
0365         fIterator = G4FastList_iterator<OBJECT>();
0366       }
0367     }
0368   };
0369 
0370 template<class OBJECT>
0371   typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::begin()
0372   {
0373     if (fAssociatedLists.empty())
0374     {
0375       return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(),
0376                                              fAssociatedLists.end(),
0377                                              &fAssociatedLists);
0378     }
0379 
0380     typename G4FastList<OBJECT>::iterator trackList_it;
0381     int i = 0;
0382 
0383     typename ManyLists::iterator it = fAssociatedLists.begin();
0384     typename ManyLists::iterator _end = fAssociatedLists.end();
0385 
0386     while (it != _end)
0387     {
0388       if (*it && (*it)->empty() == false)
0389       {
0390         trackList_it = (*it)->begin();
0391         break;
0392       }
0393       i++;
0394       it++;
0395     };
0396 
0397     if (i == fAssociatedLists.size() || it == _end)
0398     {
0399       return end();
0400     }
0401 
0402     return G4ManyFastLists_iterator<OBJECT>(trackList_it,
0403 //                                           fAssociatedLists.begin(),
0404                                             it,
0405                                            &fAssociatedLists);
0406   }
0407 
0408 template<class OBJECT>
0409 typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::end()
0410   {
0411     if (fAssociatedLists.empty())
0412     {
0413       return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(),
0414                                              fAssociatedLists.end(),
0415                                              &fAssociatedLists);
0416     }
0417 
0418     return G4ManyFastLists_iterator<OBJECT>((fAssociatedLists.end()--)->end(),
0419                                            fAssociatedLists.end(),
0420                                            &fAssociatedLists);
0421   }
0422 
0423 #include "G4ManyFastLists.icc"