424 lines
11 KiB
C++
424 lines
11 KiB
C++
//
|
|
// ********************************************************************
|
|
// * License and Disclaimer *
|
|
// * *
|
|
// * The Geant4 software is copyright of the Copyright Holders of *
|
|
// * the Geant4 Collaboration. It is provided under the terms and *
|
|
// * conditions of the Geant4 Software License, included in the file *
|
|
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
|
// * include a list of copyright holders. *
|
|
// * *
|
|
// * Neither the authors of this software system, nor their employing *
|
|
// * institutes,nor the agencies providing financial support for this *
|
|
// * work make any representation or warranty, express or implied, *
|
|
// * regarding this software system or assume any liability for its *
|
|
// * use. Please see the license in the file LICENSE and URL above *
|
|
// * for the full disclaimer and the limitation of liability. *
|
|
// * *
|
|
// * This code implementation is the result of the scientific and *
|
|
// * technical work of the GEANT4 collaboration. *
|
|
// * By using, copying, modifying or distributing the software (or *
|
|
// * any work based on the software) you agree to acknowledge its *
|
|
// * use in resulting scientific publications, and indicate your *
|
|
// * acceptance of all terms of the Geant4 Software license. *
|
|
// ********************************************************************
|
|
//
|
|
/*
|
|
* G4ManyFastLists.hh
|
|
*
|
|
* Created on: 17 nov. 2014
|
|
* Author: kara
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "G4FastList.hh"
|
|
#include <set>
|
|
|
|
template<class OBJECT>
|
|
struct G4ManyFastLists_iterator;
|
|
|
|
/*
|
|
* Roll over many list as if it was one
|
|
*/
|
|
template<class OBJECT>
|
|
class G4ManyFastLists : public G4FastList<OBJECT>::Watcher
|
|
{
|
|
protected:
|
|
using ManyLists = G4FastList<G4FastList<OBJECT>>;
|
|
ManyLists fAssociatedLists;
|
|
// TODO use "marked list" insted of vector
|
|
|
|
using WatcherSet = std::set<typename G4FastList<OBJECT>::Watcher*,
|
|
sortWatcher<OBJECT>>;
|
|
WatcherSet* fMainListWatchers;
|
|
|
|
public:
|
|
using iterator = G4ManyFastLists_iterator<OBJECT>;
|
|
|
|
G4ManyFastLists() : G4FastList<OBJECT>::Watcher(),
|
|
fAssociatedLists(), fMainListWatchers(nullptr)
|
|
{
|
|
}
|
|
|
|
~G4ManyFastLists() override = default;
|
|
|
|
virtual void NotifyDeletingList(G4FastList<OBJECT>* __list)
|
|
{
|
|
fAssociatedLists.pop(__list);
|
|
}
|
|
|
|
void AddGlobalWatcher(typename G4FastList<OBJECT>::Watcher* watcher)
|
|
{
|
|
if(fMainListWatchers == nullptr)
|
|
{
|
|
fMainListWatchers = new WatcherSet();
|
|
}
|
|
|
|
fMainListWatchers->insert(watcher);
|
|
|
|
typename ManyLists::iterator it = fAssociatedLists.begin();
|
|
typename ManyLists::iterator _end = fAssociatedLists.end();
|
|
|
|
for(;it != _end ;++it)
|
|
{
|
|
watcher->Watch(*it);
|
|
// (*it)->AddWatcher(watcher);
|
|
// (*it)->AddWatcher(watcher);
|
|
}
|
|
}
|
|
|
|
inline void Add(G4FastList<OBJECT>* __list)
|
|
{
|
|
if (__list == nullptr) return;
|
|
fAssociatedLists.push_back(__list); // TODO use the table doubling tech
|
|
//__list->AddWatcher(this);
|
|
this->Watch(__list);
|
|
|
|
if(fMainListWatchers == nullptr) return;
|
|
|
|
auto it_watcher = fMainListWatchers->begin();
|
|
auto end_watcher = fMainListWatchers->end();
|
|
|
|
// G4cout << "G4ManyFastLists::Add -- N watchers ="
|
|
// << fMainListWatchers->size()
|
|
// << G4endl;
|
|
|
|
for(;it_watcher != end_watcher ;++it_watcher)
|
|
{
|
|
// G4cout << " *** *** *** WATCH --- "
|
|
// << (*it_watcher)->GetWatcherName()
|
|
// << G4endl;
|
|
(*it_watcher)->Watch(__list);
|
|
}
|
|
|
|
if(__list->empty() == false)
|
|
{
|
|
it_watcher = fMainListWatchers->begin();
|
|
|
|
for(;it_watcher != end_watcher ;++it_watcher)
|
|
{
|
|
typename G4FastList<OBJECT>::iterator it_obj = __list->begin();
|
|
for(;it_obj != __list->end() ;++it_obj)
|
|
{
|
|
// G4cout << " *** *** *** NOTIFY ADD OBJ --- "
|
|
// << (*it_watcher)->GetWatcherName()
|
|
// << G4endl;
|
|
|
|
(*it_watcher)->NotifyAddObject(*it_obj,__list);
|
|
}
|
|
}
|
|
}
|
|
// else
|
|
// {
|
|
// G4cout << "__list->empty() == true" << G4endl;
|
|
// }
|
|
|
|
/*
|
|
typename ManyLists::const_iterator __it = fAssociatedLists
|
|
.begin();
|
|
typename ManyLists::const_iterator __end = fAssociatedLists
|
|
.end();
|
|
for (; __it != __end; __it++)
|
|
{
|
|
assert(*__it);
|
|
}
|
|
*/
|
|
}
|
|
|
|
inline void Remove(G4FastList<OBJECT>* __list)
|
|
{
|
|
if (__list == nullptr) return;
|
|
fAssociatedLists.pop(__list); // TODO use the table doubling tech
|
|
__list->RemoveWatcher(this);
|
|
this->StopWatching(__list);
|
|
|
|
auto it = fMainListWatchers->begin();
|
|
auto _end = fMainListWatchers->end();
|
|
|
|
for(;it != _end ;++it)
|
|
{
|
|
(*it)->StopWatching(__list);
|
|
}
|
|
|
|
// typename ManyLists::node* __node = __list->GetListNode();
|
|
// if(__node)
|
|
// {
|
|
// __list->SetListNode(0);
|
|
// delete __node;
|
|
// }
|
|
}
|
|
|
|
inline bool Holds(OBJECT* __track) const
|
|
{
|
|
typename ManyLists::const_iterator __it = fAssociatedLists.begin();
|
|
typename ManyLists::const_iterator __end = fAssociatedLists.end();
|
|
for (; __it != __end; __it++)
|
|
if ((*__it)->Holds(__track)) return true;
|
|
return false;
|
|
}
|
|
|
|
inline size_t size() const
|
|
{
|
|
size_t __size(0);
|
|
for (auto __it : fAssociatedLists)
|
|
{
|
|
__size += __it->size();
|
|
}
|
|
return __size;
|
|
}
|
|
|
|
inline void RemoveLists()
|
|
{
|
|
typename ManyLists::iterator __it = fAssociatedLists.begin();
|
|
typename ManyLists::iterator __end = fAssociatedLists.end();
|
|
for (; __it != __end; __it++)
|
|
{
|
|
if (*__it)
|
|
{
|
|
(*__it)->clear();
|
|
typename ManyLists::iterator next = __it;
|
|
next++;
|
|
Remove(*__it);
|
|
typename ManyLists::node* __node = __it.GetNode();
|
|
if(__node)
|
|
{
|
|
__node->GetObject()->SetListNode(nullptr);
|
|
delete __node;
|
|
}
|
|
// delete (*__it);
|
|
|
|
__it = next;
|
|
}
|
|
}
|
|
fAssociatedLists.clear();
|
|
}
|
|
|
|
inline void ClearLists()
|
|
{
|
|
typename ManyLists::iterator __it = fAssociatedLists.begin();
|
|
typename ManyLists::iterator __end = fAssociatedLists.end();
|
|
for (; __it != __end; __it++)
|
|
if (*__it) (*__it)->clear();
|
|
}
|
|
|
|
inline iterator begin();
|
|
inline iterator end();
|
|
|
|
void pop(OBJECT*);
|
|
};
|
|
|
|
template<class OBJECT>
|
|
struct G4ManyFastLists_iterator
|
|
{
|
|
using ManyLists = G4FastList<G4FastList<OBJECT>>;
|
|
|
|
using _Self = G4ManyFastLists_iterator;
|
|
using _Node = G4FastListNode<OBJECT>;
|
|
|
|
G4FastList_iterator<OBJECT> fIterator;
|
|
typename ManyLists::iterator fCurrentListIt;
|
|
ManyLists* fLists;
|
|
|
|
private:
|
|
G4ManyFastLists_iterator() = default;
|
|
|
|
public:
|
|
explicit G4ManyFastLists_iterator(G4FastList_iterator<OBJECT> __x,
|
|
typename ManyLists::iterator __it,
|
|
ManyLists* __lists) :
|
|
fIterator(__x), fCurrentListIt(__it), fLists(__lists)
|
|
{
|
|
}
|
|
|
|
G4ManyFastLists_iterator(const G4ManyFastLists_iterator& __x) = default;
|
|
_Self& operator=(const G4ManyFastLists_iterator& __x) = default;
|
|
|
|
_Node* GetNode()
|
|
{
|
|
return fIterator.GetNode();
|
|
}
|
|
|
|
G4FastList<OBJECT>* GetTrackList()
|
|
{
|
|
return *fCurrentListIt;
|
|
}
|
|
|
|
OBJECT* operator*()
|
|
{
|
|
return *fIterator;
|
|
}
|
|
const OBJECT* operator*() const
|
|
{
|
|
return *fIterator;
|
|
}
|
|
OBJECT* operator->()
|
|
{
|
|
return *fIterator;
|
|
}
|
|
const OBJECT* operator->() const
|
|
{
|
|
return *fIterator;
|
|
}
|
|
|
|
_Self UpdateToNextValidList();
|
|
_Self& operator++();
|
|
|
|
_Self operator++(int)
|
|
{
|
|
return operator++();
|
|
}
|
|
|
|
_Self&
|
|
operator--()
|
|
{
|
|
if (fLists->empty())
|
|
{
|
|
fIterator = G4FastList_iterator<OBJECT>();
|
|
return *this;
|
|
}
|
|
if (fCurrentListIt == fLists->begin())
|
|
{
|
|
if (fIterator == (*fCurrentListIt)->begin())
|
|
{
|
|
fIterator = G4FastList_iterator<OBJECT>();
|
|
return *this;
|
|
}
|
|
}
|
|
|
|
if (fCurrentListIt == fLists->end())
|
|
{
|
|
fCurrentListIt--;
|
|
fIterator = (*fCurrentListIt)->end();
|
|
}
|
|
else if (fIterator == (*fCurrentListIt)->begin())
|
|
{
|
|
fCurrentListIt--;
|
|
fIterator = (*fCurrentListIt)->end();
|
|
}
|
|
|
|
fIterator--;
|
|
|
|
while (((*fCurrentListIt)->empty() || fIterator.GetNode() == nullptr
|
|
|| fIterator.GetNode()->GetObject() == nullptr)
|
|
&& fCurrentListIt != fLists->begin())
|
|
{
|
|
fIterator = (*fCurrentListIt)->begin();
|
|
fCurrentListIt--;
|
|
fIterator = (*fCurrentListIt)->end();
|
|
fIterator--;
|
|
}
|
|
|
|
if (fIterator.GetNode() == nullptr && fCurrentListIt == fLists->begin())
|
|
{
|
|
fIterator = G4FastList_iterator<OBJECT>();
|
|
return *this;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
_Self operator--(int)
|
|
{
|
|
return operator--();
|
|
}
|
|
|
|
G4bool operator==(const _Self& __x) const
|
|
{
|
|
return (fIterator == __x.fIterator && fCurrentListIt == __x.fCurrentListIt);
|
|
} // Fast check
|
|
|
|
G4bool operator!=(const _Self& __x) const
|
|
{
|
|
return !(this->operator ==(__x));
|
|
}
|
|
|
|
protected:
|
|
void HasReachedEnd()
|
|
{
|
|
if (fLists->empty() == false)
|
|
{
|
|
fIterator = (*(fLists->end()--))->end();
|
|
}
|
|
else
|
|
{
|
|
fIterator = G4FastList_iterator<OBJECT>();
|
|
}
|
|
}
|
|
};
|
|
|
|
template<class OBJECT>
|
|
typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::begin()
|
|
{
|
|
if (fAssociatedLists.empty())
|
|
{
|
|
return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(),
|
|
fAssociatedLists.end(),
|
|
&fAssociatedLists);
|
|
}
|
|
|
|
typename G4FastList<OBJECT>::iterator trackList_it;
|
|
int i = 0;
|
|
|
|
typename ManyLists::iterator it = fAssociatedLists.begin();
|
|
typename ManyLists::iterator _end = fAssociatedLists.end();
|
|
|
|
while (it != _end)
|
|
{
|
|
if (*it && (*it)->empty() == false)
|
|
{
|
|
trackList_it = (*it)->begin();
|
|
break;
|
|
}
|
|
i++;
|
|
it++;
|
|
};
|
|
|
|
if (i == fAssociatedLists.size() || it == _end)
|
|
{
|
|
return end();
|
|
}
|
|
|
|
return G4ManyFastLists_iterator<OBJECT>(trackList_it,
|
|
// fAssociatedLists.begin(),
|
|
it,
|
|
&fAssociatedLists);
|
|
}
|
|
|
|
template<class OBJECT>
|
|
typename G4ManyFastLists<OBJECT>::iterator G4ManyFastLists<OBJECT>::end()
|
|
{
|
|
if (fAssociatedLists.empty())
|
|
{
|
|
return G4ManyFastLists_iterator<OBJECT>(G4FastList_iterator<OBJECT>(),
|
|
fAssociatedLists.end(),
|
|
&fAssociatedLists);
|
|
}
|
|
|
|
return G4ManyFastLists_iterator<OBJECT>((fAssociatedLists.end()--)->end(),
|
|
fAssociatedLists.end(),
|
|
&fAssociatedLists);
|
|
}
|
|
|
|
#include "G4ManyFastLists.icc"
|