ROOT logo
// $Id: AList.h 2759 2012-06-07 01:15:27Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

#ifndef GledCore_AList_H
#define GledCore_AList_H

#include <Glasses/ZGlass.h>

/**************************************************************************/
// AList - abstract base glass for collections of lens references         //
/**************************************************************************/

class AList : public ZGlass
{
  MAC_RNR_FRIENDS(AList);

  friend class Saturn;
  friend class ZQueen;

public:

  /************************************************************************/
  // ElRep - list-element representation; needed for list ops and GUI     //
  /************************************************************************/

  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;

  // Three types of *unique* element identification.
  // Each sub-class must support *exactly* one method.
  // 13.8.06: why is ET_Nil not ok? Setting it for ZDeque (was ET_Lens so far).
  enum ElType_e { ET_Nil, ET_Lens, ET_Id, ET_Label };

  /************************************************************************/
  // Stepper, generick iteration-driver. Makes rootcint nervous.
  /************************************************************************/

#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;		//  X{GS} 7 Value(-width=>4, -join=>1)
  CID_t			mCid;		//  X{GS} 7 Value(-width=>4, -join=>1)
  Int_t			mSize;		//  X{G}  7 ValOut(-width=>5)

  TimeStamp_t		mListTimeStamp; //! X{GS}
  GMutex	 	mListMutex;   	//! X{r}

  // ZGlass reference management, extensions for lists.

  virtual void  reference_all();
  virtual void  unreference_all();
  virtual void  reference_list_elms();   // Override for optimization.
  virtual void  unreference_list_elms(); // Override for optimization.
  virtual Int_t remove_references_to(ZGlass* lens) = 0; // ?? Is this ok ?? It is declared and implemented in ZGlass.

  // AList methods.

  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 ~AList() {}

  virtual AList* AsAList() { return this; }

  // ZGlass reference management, extensions for lists.
  virtual Int_t RebuildAllRefs(An_ID_Demangler* idd);
  virtual Int_t RebuildListRefs(An_ID_Demangler* idd) = 0;

  virtual void ClearAllReferences();
  virtual void ClearList() = 0 ;        // X{E}

  void RemoveLensesViaQueen(Bool_t recurse=false); // X{Ed}

  // List specific interface.

  void   SetElementFID(FID_t fid);      // X{E}
  Int_t  Size()    { return mSize; }
  Bool_t IsEmpty() { return mSize==0; }

  virtual Bool_t Has(ZGlass* g); // Override for optimization!

  // Copying of list elements.
  // One can also use Steppers but lists must not be changed during that.
  virtual TimeStamp_t CopyListElReps(lElRep_t& dest, bool copy_zeros=false);

  virtual TimeStamp_t CopyList(lpZGlass_t& dest, bool copy_zeros=false, bool do_eyerefs=false);
  virtual void        ReleaseListCopyEyeRefs(lpZGlass_t& dest);

  template <class GLASS>
  TimeStamp_t CopyListByGlass(list<GLASS*>& dest, bool copy_zeros=false, bool do_eyerefs=false)
  {
    GMutexHolder lck(mListMutex);
    Stepper<GLASS> s(this, copy_zeros);
    while (s.step())
    {
      if (do_eyerefs && *s) s->IncEyeRefCount();
      dest.push_back(*s);
    }
    return mListTimeStamp;
  }
  template <class GLASS>
  void ReleaseListCopyEyeRefsByGlass(list<GLASS*>& dest)
  {
    for (typename list<GLASS*>::iterator i = dest.begin(); i != dest.end(); ++i)
    {
      if (*i) (*i)->DecEyeRefCount();
    }
  }

  template <class CLASS>
  TimeStamp_t CopyListByClass(list<CLASS*>& dest, bool copy_zeros=false, bool do_eyerefs=false)
  {
    GMutexHolder lck(mListMutex);
    Stepper<CLASS> s(this, copy_zeros);
    while (s.step())
    {
      if (do_eyerefs && *s) dynamic_cast<ZGlass*>(*s)->IncEyeRefCount();
      dest.push_back(*s);
    }
    return mListTimeStamp;
  }
  template <class CLASS>
  void ReleaseListCopyEyeRefsByClass(list<CLASS*>& dest)
  {
    for (typename list<CLASS*>::iterator i = dest.begin(); i != dest.end(); ++i)
    {
      if (*i) dynamic_cast<ZGlass*>(*i)->DecEyeRefCount();
    }
  }

  // Searching of elements by name.
  virtual ZGlass* GetElementByName (const TString& name);
  virtual Int_t   GetElementsByName(const TString& name, lpZGlass_t& dest);

  void DumpElements(Bool_t dump_zeros=false); //! X{E} 7 MCWButt()

  //----------------------------------------------------------------------
  // ElRep properties and supported operations.
  // These statements are a promise of implementation for methods below.
  //----------------------------------------------------------------------

  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; }

  //----------------------------------------------------------------------
  // List element handling operations.
  // Not declared here, as there is no unique interface.
  // MIR-makers and GUI rely on naming conventions!
  //----------------------------------------------------------------------

  // General interface
  virtual void  Add      (ZGlass* lens) = 0;   // X{E} C{1}
  virtual Int_t RemoveAll(ZGlass* lens) = 0;   // X{E} C{1}

  // Deque interface
  // `````````````````````````````````````````````````````````````````````
  // Pop methods *must* return the poped element if ResultReq is set.
  // virtual ZGlass* FrontElement();          // X{E} C{0}
  // virtual ZGlass* BackElement();           // X{E} C{0}
  // virtual void    PushBack(ZGlass* lens);  // X{E} C{1}
  // virtual ZGlass* PopBack();               // X{E} C{0}
  // virtual void    PushFront(ZGlass* lens); // X{E} C{1}
  // virtual ZGlass* PopFront();              // X{E} C{0}

  // Insert-by-lens-pointer interface;
  // `````````````````````````````````````````````````````````````````````
  // virtual void Insert(ZGlass* lens, ZGlass* before);           // X{E} C{1}
  // virtual void Remove(ZGlass* lens);                           // X{E} C{1}

  // Insert-by-id interface
  // `````````````````````````````````````````````````````````````````````
  // virtual void InsertById(ZGlass* lens, Int_t before_id);      // X{E} C{1}
  // virtual void RemoveById(Int_t id_to_remove);                 // X{E} C{0}

  // Set-by-id interface
  // `````````````````````````````````````````````````````````````````````
  // virtual void SetElementById(ZGlass* lens, Int_t target_id);  // X{E} C{1}

  // Set-by-label interface
  // `````````````````````````````````````````````````````````````````````
  // virtual void SetElementByLabel(ZGlass* lens, TString label,
  //                                Bool_t create=true);          // X{E} C{1}
  // virtual void AddLabel(TString label);                        // X{E} C{0}
  // virtual void RemoveLabel(TString label);                     // X{E} C{0}
  // virtual void ChangeLabel(TString label, TString new_label);  // X{E} C{0}
  //
  // Insert-by-label [external/user-defined label ordering]
  // `````````````````````````````````````````````````````````````````````
  // virtual void InsertByLabel(ZGlass* lens, TString label,
  //                            TString before);                  // X{E} C{1}
  // virtual void InsertLabel(TString label, TString before);     // X{E} C{0}

  //----------------------------------------------------------------------
  // MIR makers. Eventually virtual.
  //----------------------------------------------------------------------

  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);

  //----------------------------------------------------------------------
  // Stamping methods ... coded here for all sub-classes
  //----------------------------------------------------------------------

  // ZGlass virtuals
  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();

  // ElRep BetaElRep(Ray& ray);
  // ElRep GammaElRep(Ray& ray);

#include "AList.h7"
  ClassDef(AList, 1); // Abstract container base-class.
}; // endclass AList



#ifndef __CINT__
/* inline template */
template <> inline bool AList::Stepper<ZGlass>::is_ok()
{ m_current = get_lens(); return (m_current != 0 || m_return_zeros); }
#endif

#endif
 AList.h:1
 AList.h:2
 AList.h:3
 AList.h:4
 AList.h:5
 AList.h:6
 AList.h:7
 AList.h:8
 AList.h:9
 AList.h:10
 AList.h:11
 AList.h:12
 AList.h:13
 AList.h:14
 AList.h:15
 AList.h:16
 AList.h:17
 AList.h:18
 AList.h:19
 AList.h:20
 AList.h:21
 AList.h:22
 AList.h:23
 AList.h:24
 AList.h:25
 AList.h:26
 AList.h:27
 AList.h:28
 AList.h:29
 AList.h:30
 AList.h:31
 AList.h:32
 AList.h:33
 AList.h:34
 AList.h:35
 AList.h:36
 AList.h:37
 AList.h:38
 AList.h:39
 AList.h:40
 AList.h:41
 AList.h:42
 AList.h:43
 AList.h:44
 AList.h:45
 AList.h:46
 AList.h:47
 AList.h:48
 AList.h:49
 AList.h:50
 AList.h:51
 AList.h:52
 AList.h:53
 AList.h:54
 AList.h:55
 AList.h:56
 AList.h:57
 AList.h:58
 AList.h:59
 AList.h:60
 AList.h:61
 AList.h:62
 AList.h:63
 AList.h:64
 AList.h:65
 AList.h:66
 AList.h:67
 AList.h:68
 AList.h:69
 AList.h:70
 AList.h:71
 AList.h:72
 AList.h:73
 AList.h:74
 AList.h:75
 AList.h:76
 AList.h:77
 AList.h:78
 AList.h:79
 AList.h:80
 AList.h:81
 AList.h:82
 AList.h:83
 AList.h:84
 AList.h:85
 AList.h:86
 AList.h:87
 AList.h:88
 AList.h:89
 AList.h:90
 AList.h:91
 AList.h:92
 AList.h:93
 AList.h:94
 AList.h:95
 AList.h:96
 AList.h:97
 AList.h:98
 AList.h:99
 AList.h:100
 AList.h:101
 AList.h:102
 AList.h:103
 AList.h:104
 AList.h:105
 AList.h:106
 AList.h:107
 AList.h:108
 AList.h:109
 AList.h:110
 AList.h:111
 AList.h:112
 AList.h:113
 AList.h:114
 AList.h:115
 AList.h:116
 AList.h:117
 AList.h:118
 AList.h:119
 AList.h:120
 AList.h:121
 AList.h:122
 AList.h:123
 AList.h:124
 AList.h:125
 AList.h:126
 AList.h:127
 AList.h:128
 AList.h:129
 AList.h:130
 AList.h:131
 AList.h:132
 AList.h:133
 AList.h:134
 AList.h:135
 AList.h:136
 AList.h:137
 AList.h:138
 AList.h:139
 AList.h:140
 AList.h:141
 AList.h:142
 AList.h:143
 AList.h:144
 AList.h:145
 AList.h:146
 AList.h:147
 AList.h:148
 AList.h:149
 AList.h:150
 AList.h:151
 AList.h:152
 AList.h:153
 AList.h:154
 AList.h:155
 AList.h:156
 AList.h:157
 AList.h:158
 AList.h:159
 AList.h:160
 AList.h:161
 AList.h:162
 AList.h:163
 AList.h:164
 AList.h:165
 AList.h:166
 AList.h:167
 AList.h:168
 AList.h:169
 AList.h:170
 AList.h:171
 AList.h:172
 AList.h:173
 AList.h:174
 AList.h:175
 AList.h:176
 AList.h:177
 AList.h:178
 AList.h:179
 AList.h:180
 AList.h:181
 AList.h:182
 AList.h:183
 AList.h:184
 AList.h:185
 AList.h:186
 AList.h:187
 AList.h:188
 AList.h:189
 AList.h:190
 AList.h:191
 AList.h:192
 AList.h:193
 AList.h:194
 AList.h:195
 AList.h:196
 AList.h:197
 AList.h:198
 AList.h:199
 AList.h:200
 AList.h:201
 AList.h:202
 AList.h:203
 AList.h:204
 AList.h:205
 AList.h:206
 AList.h:207
 AList.h:208
 AList.h:209
 AList.h:210
 AList.h:211
 AList.h:212
 AList.h:213
 AList.h:214
 AList.h:215
 AList.h:216
 AList.h:217
 AList.h:218
 AList.h:219
 AList.h:220
 AList.h:221
 AList.h:222
 AList.h:223
 AList.h:224
 AList.h:225
 AList.h:226
 AList.h:227
 AList.h:228
 AList.h:229
 AList.h:230
 AList.h:231
 AList.h:232
 AList.h:233
 AList.h:234
 AList.h:235
 AList.h:236
 AList.h:237
 AList.h:238
 AList.h:239
 AList.h:240
 AList.h:241
 AList.h:242
 AList.h:243
 AList.h:244
 AList.h:245
 AList.h:246
 AList.h:247
 AList.h:248
 AList.h:249
 AList.h:250
 AList.h:251
 AList.h:252
 AList.h:253
 AList.h:254
 AList.h:255
 AList.h:256
 AList.h:257
 AList.h:258
 AList.h:259
 AList.h:260
 AList.h:261
 AList.h:262
 AList.h:263
 AList.h:264
 AList.h:265
 AList.h:266
 AList.h:267
 AList.h:268
 AList.h:269
 AList.h:270
 AList.h:271
 AList.h:272
 AList.h:273
 AList.h:274
 AList.h:275
 AList.h:276
 AList.h:277
 AList.h:278
 AList.h:279
 AList.h:280
 AList.h:281
 AList.h:282
 AList.h:283
 AList.h:284
 AList.h:285
 AList.h:286
 AList.h:287
 AList.h:288
 AList.h:289
 AList.h:290
 AList.h:291
 AList.h:292
 AList.h:293
 AList.h:294
 AList.h:295
 AList.h:296
 AList.h:297
 AList.h:298
 AList.h:299
 AList.h:300
 AList.h:301
 AList.h:302
 AList.h:303
 AList.h:304
 AList.h:305
 AList.h:306
 AList.h:307
 AList.h:308
 AList.h:309
 AList.h:310
 AList.h:311
 AList.h:312
 AList.h:313
 AList.h:314
 AList.h:315
 AList.h:316
 AList.h:317
 AList.h:318
 AList.h:319
 AList.h:320
 AList.h:321
 AList.h:322
 AList.h:323
 AList.h:324
 AList.h:325
 AList.h:326
 AList.h:327
 AList.h:328
 AList.h:329
 AList.h:330
 AList.h:331
 AList.h:332
 AList.h:333
 AList.h:334
 AList.h:335
 AList.h:336
 AList.h:337
 AList.h:338
 AList.h:339
 AList.h:340
 AList.h:341
 AList.h:342
 AList.h:343
 AList.h:344
 AList.h:345
 AList.h:346
 AList.h:347
 AList.h:348
 AList.h:349
 AList.h:350
 AList.h:351
 AList.h:352
 AList.h:353
 AList.h:354
 AList.h:355
 AList.h:356
 AList.h:357
 AList.h:358
 AList.h:359
 AList.h:360
 AList.h:361
 AList.h:362
 AList.h:363
 AList.h:364
 AList.h:365
 AList.h:366
 AList.h:367
 AList.h:368
 AList.h:369
 AList.h:370
 AList.h:371
 AList.h:372
 AList.h:373
 AList.h:374
 AList.h:375
 AList.h:376
 AList.h:377
 AList.h:378
 AList.h:379
 AList.h:380
 AList.h:381