#ifndef GledCore_AList_H
#define GledCore_AList_H
#include <Glasses/ZGlass.h>
class AList : public ZGlass
{
MAC_RNR_FRIENDS(AList);
friend class Saturn;
friend class ZQueen;
public:
class ElRep
{
public:
ZGlass* fLens;
Int_t fId;
TString fLabel;
ElRep(ZGlass* l=0) : fLens(l), fId(-1) {}
ElRep(ZGlass* l, Int_t i) : fLens(l), fId(i) {}
ElRep(ZGlass* l, const TString& lab) : fLens(l), fId(-1), fLabel(lab) {}
ElRep(ZGlass* l, Int_t i, const TString& lab) : fLens(l), fId(i), fLabel(lab) {}
ZGlass* get_lens() const { return fLens; }
Int_t get_id() const { return fId; }
TString get_label() const { return fLabel; }
const TString& ref_label() const { return fLabel; }
};
typedef list<ElRep> lElRep_t;
typedef list<ElRep>::iterator lElRep_i;
enum ElType_e { ET_Nil, ET_Lens, ET_Id, ET_Label };
#ifndef __CINT__
class stepper_base
{
protected:
bool m_first_p;
public:
stepper_base() : m_first_p(true) {}
virtual ~stepper_base() {}
virtual bool step() = 0;
virtual ZGlass* lens() = 0;
virtual ElRep elrep() = 0;
};
template<class Cont>
class stepper_imp : public stepper_base
{
protected:
typedef typename Cont::iterator iterator_type;
iterator_type m_iter, m_end;
public:
stepper_imp(iterator_type b, iterator_type e) :
stepper_base(), m_iter(b), m_end(e) {}
virtual bool step() {
if(m_iter == m_end) return false;
if(m_first_p)
m_first_p = false;
else
++m_iter;
return (m_iter != m_end);
}
virtual ZGlass* lens() { return m_iter.lens(); }
virtual ElRep elrep() { return m_iter.elrep(); }
};
public:
template<class G=ZGlass>
class Stepper
{
protected:
stepper_base* m_stepper_imp;
G* m_current;
bool m_return_zeros;
bool is_ok()
{
m_current = dynamic_cast<G*>(get_lens());
return (m_current != 0 || m_return_zeros);
}
public:
Stepper(AList* l, bool return_zeros=false) :
m_stepper_imp(l->make_stepper_imp()), m_current(0),
m_return_zeros(return_zeros) {}
Stepper(stepper_base* imp, bool return_zeros=false) :
m_stepper_imp(imp), m_current(0),
m_return_zeros(return_zeros) {}
~Stepper() { delete m_stepper_imp; }
void reset(AList* l, bool return_zeros=false) {
delete m_stepper_imp;
m_stepper_imp = l->make_stepper_imp();
m_current = 0;
m_return_zeros = return_zeros;
}
bool step() {
do {
if(! m_stepper_imp->step()) return false;
} while(! is_ok());
return true;
}
ZGlass* get_lens() { return m_stepper_imp->lens(); }
AList::ElRep get_elrep() { return m_stepper_imp->elrep(); }
G* operator->() { return m_current; }
G* operator*() { return m_current; }
};
virtual stepper_base* make_stepper_imp() { return 0; }
#endif
private:
void _init();
protected:
LID_t mLid;
CID_t mCid;
Int_t mSize;
TimeStamp_t mListTimeStamp;
GMutex mListMutex;
virtual void reference_all();
virtual void unreference_all();
virtual void reference_list_elms();
virtual void unreference_list_elms();
virtual Int_t remove_references_to(ZGlass* lens) = 0;
virtual void new_element_check(ZGlass* lens);
virtual void clear_list() = 0;
public:
AList(const Text_t* n="AList", const Text_t* t=0) :
ZGlass(n,t), mListMutex(GMutex::recursive) { _init(); }
virtual Int_t RebuildAllRefs(An_ID_Demangler* idd);
virtual Int_t RebuildListRefs(An_ID_Demangler* idd) = 0;
virtual void ClearAllReferences();
virtual void ClearList() = 0 ;
void RemoveLensesViaQueen(Bool_t recurse=false);
void SetElementFID(FID_t fid);
Int_t Size() { return mSize; }
Bool_t IsEmpty() { return mSize==0; }
virtual Bool_t Has(ZGlass* g);
virtual TimeStamp_t CopyList(lpZGlass_t& dest, bool copy_zeros=false);
virtual TimeStamp_t CopyListElReps(lElRep_t& dest, bool copy_zeros=false);
template <class GLASS>
TimeStamp_t CopyListByGlass(list<GLASS*>& dest) {
GMutexHolder lck(mListMutex);
Stepper<GLASS> s(this);
while(s.step())
dest.push_back(*s);
return mListTimeStamp;
}
virtual ZGlass* GetElementByName (const TString& name);
virtual Int_t GetElementsByName(const TString& name, lpZGlass_t& dest);
void DumpElements(Bool_t dump_zeros=false);
virtual ElType_e el_type() { return ET_Nil; }
virtual bool elrep_has_id() { return false; }
virtual bool elrep_has_label() { return false; }
virtual bool elrep_can_hold_zero() { return false; }
virtual bool elrep_can_edit_label() { return false; }
virtual bool list_deque_ops() { return false; }
virtual bool list_insert_lens_ops() { return false; }
virtual bool list_insert_id_ops() { return false; }
virtual bool list_set_id_ops() { return false; }
virtual bool list_set_label_ops() { return false; }
virtual bool list_insert_label_ops() { return false; }
virtual void Add (ZGlass* lens) = 0;
virtual Int_t RemoveAll(ZGlass* lens) = 0;
ZMIR* MkMir_Add(ZGlass* lens);
ZMIR* MkMir_RemoveAll(ZGlass* lens);
ZMIR* MkMir_PushBack(ZGlass* lens);
ZMIR* MkMir_PopBack();
ZMIR* MkMir_PushFront(ZGlass* lens);
ZMIR* MkMir_PopFront();
ZMIR* MkMir_Insert(ZGlass* lens, ElRep& elrep);
ZMIR* MkMir_Remove(ElRep& elrep);
ZMIR* MkMir_SetElement(ZGlass* lens, ElRep& elrep);
ZMIR* MkMir_AddLabel(const TString& label);
ZMIR* MkMir_RemoveLabel(const TString& label);
ZMIR* MkMir_ChangeLabel(const TString& label, TString new_label);
ZMIR* MkMir_InsertByLabel(ZGlass* lens, const TString& label, const TString& before);
ZMIR* MkMir_InsertLabel(const TString& label, const TString& before);
virtual void SetStamps(TimeStamp_t s)
{ ZGlass::SetStamps(s); mListTimeStamp = s; }
virtual TimeStamp_t StampListPushBack(ZGlass* lens, Int_t id=-1);
virtual TimeStamp_t StampListPopBack();
virtual TimeStamp_t StampListPushFront(ZGlass* lens, Int_t id=-1);
virtual TimeStamp_t StampListPopFront();
virtual TimeStamp_t StampListInsert(ZGlass* lens, Int_t id, ZGlass* before);
virtual TimeStamp_t StampListInsert(ZGlass* lens, Int_t id, Int_t before_id);
virtual TimeStamp_t StampListRemove(ZGlass* lens);
virtual TimeStamp_t StampListRemove(ZGlass* lens, Int_t id);
virtual TimeStamp_t StampListElementSet(ZGlass* lens, Int_t id);
virtual TimeStamp_t StampListElementSet(ZGlass* lens, const TString& label);
virtual TimeStamp_t StampListInsertLabel(ZGlass* lens, const TString& label, const TString& before);
virtual TimeStamp_t StampListRemoveLabel(ZGlass* lens, const TString& label);
virtual TimeStamp_t StampListRebuild();
virtual TimeStamp_t StampListClear();
#include "AList.h7"
ClassDef(AList, 1);
};
#ifndef __CINT__
template <> inline bool AList::Stepper<ZGlass>::is_ok()
{ m_current = get_lens(); return (m_current != 0 || m_return_zeros); }
#endif
#endif