ROOT logo
// @(#)root/cont:$Id: TRef.cxx 20877 2007-11-19 11:17:07Z rdm $
// Author: Rene Brun   28/09/2001

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//
// TRef
//
// Persistent Reference link to a TObject
// A TRef is a lightweight object pointing to any TObject.
// This object can be used instead of normal C++ pointers in case
//  - the referenced object R and the pointer P are not written to the same file
//  - P is read before R
//  - R and P are written to different Tree branches
//
// When a top level object (eg Event *event) is a tree/graph of many objects,
// the normal ROOT Streaming mechanism ensures that only one copy of each object
// in the tree/graph is written to the output buffer to avoid circular
// dependencies.
// However if the object event is split into several files or into several
// branches of one or more Trees, normal C++ pointers cannot be used because
// each I/O operation will write the referenced objects.
// When a TRef is used to point to a TObject *robj, for example in a class with
//     TRef  fRef;
// one can do:
//     fRef = robj;  //to set the pointer
// This TRef and robj can be written with two different I/O calls
// in the same or different files, in the same or different branches of a Tree.
//
// If the TRef is read and the referenced object has not yet been read,
// the TRef will return a null pointer. As soon as the referenced object
// will be read, the TRef will point to it. If the referenced object is
// contained in a TTree it can be autoloaded using the TBranchRef mechanism,
// which is set up by simply calling TTree::BranchRef().
//
// TRef also supports the complex situation where a TFile is updated
// multiple times on the same machine or a different machine.
//
// How does it work
// ----------------
// A TRef is itself a TObject with an additional transient pointer fPID.
// When the statement fRef = robj is executed, the following actions happen:
//   - The pointer fPID is set to the current TProcessID.
//   - The current ObjectNumber (see below) is incremented by one.
//   - robj::fUniqueID is set to ObjectNumber.
//   - In the fPID object, the element fObjects[ObjectNumber] is set to robj
//   - ref::fUniqueID is also set to ObjectNumber.
// After having set fRef, one can immediatly return the value of robj
// using fRef.GetObject(). This function returns directly fObjects[fUniqueID]
// from the fPID object.
//
// When the TRef is written, the process id number pidf of fPID is written
// in addition to the TObject part of TRef (fBits,fUniqueID).
// When the TRef is read, its pointer fPID is set to the value
// stored in the TObjArray of TFile::fProcessIDs (fProcessIDs[pidf]).
// The pidf is stored in the bits 24->31 of the fUniqueID of the TRef.
// This implies that the number of TRefs in one process should not
// exceed 2**23 = 8388608 and that the number of processes (different jobs)
// writing TRefs to one file should be less than 256.
// See section "ObjectNumber" below for a recipee to minimize the object count.
// If the objectnumber exceeds this limit, it could be the sign that:
//   -The object count is never reset (see below)
//   -TRef is misused.
//
// When a referenced object robj is written, TObject::Streamer writes
// in addition to the standard (fBits,fUniqueID) the pidf.
// When this robj is read by TObject::Streamer, the pidf is read.
// At this point, robj is entered into the table of objects of the TProcessID
// corresponding to pidf.
//
// WARNING1: If MyClass is the class of the referenced object, The TObject
//          part of MyClass must be Streamed. One should not
//          call MyClass::Class()->IgnoreTObjectStreamer()
//
//
// WARNING2: A TRef cannot point to another TRef.
//
//
// ObjectNumber
// ------------
// When an object is referenced (see TRef assignement operator or TRefArray::Add)
// a unique identifier is computed and stored in both the fUniqueID of the
// referenced and referencing object. This uniqueID is computed by incrementing
// by one the static global in TProcessID::fgNumber. fUniqueID is some sort of
// serial object number in the current session. One can retrieve at any time
// the current value of fgNumber by calling the static function TProcessID::GetObjectCount
// or set this number via TProcessID::SetObjectCount.
// To avoid a growing table of fObjects in TProcessID, in case, for example,
// one processes many events in a loop, it might be necessary to reset the
// ObjectNumber at the end of processing of one event. See an example
// in $ROOTSYS/test/Event.cxx (look at function Build).
// The value of ObjectNumber (say saveNumber=TProcessID::GetObjectCount()) may be
// saved at the beginning of one event and reset to this original value
// at the end of the event via TProcessID::SetObjectCount(saveNumber). These
// actions may be stacked.
//
// Action on Demand
// ----------------
// The normal behaviour of a TRef has been described above. In addition,
// TRef supports also "Actions on Demand". It may happen that the object
// referenced is not yet in memory, on a separate file or not yet computed.
// In this case TRef is able to automatically execute an action:
//   - call to a compiled function (static function of member function)
//   - call to an interpreted function
//   - execution of a CINT script
//
// How to select this option?
// In the definition of the TRef data member in the original class, do:
//   TRef  fRef;   //EXEC:execName. points to something
// When the special keyword "EXEC:" is found in the comment field of the member,
// the next string is assumed to be the name of a TExec object.
// When a file is connected, the dictionary of the classes on the file
// is read in memory (see TFile::ReadStreamerInfo). When the TStreamerElement
// object is read, a TExec object is automatically created with the name
// specified after the keywork "EXEC:" in case a TExec with a same name does
// not already exist.
// The action to be executed via this TExec can be specified with:
//    - a call to the TExec constructor, if the constructor is called before
//      opening the file.
//    - a call to TExec::SetAction at any time.
//      One can compute a pointer to an existing TExec with a name with:
//        TExec *myExec = gROOT->GetExec(execName);
//      myExec->SetAction(actionCommand); where
//      - actionCommand is a string containing a CINT instruction. Examples:
//          myExec->SetAction("LoadHits()");
//          myExec->SetAction(".x script.C");
//
// When a TRef is dereferenced via TRef::GetObject, its TExec will be
// automatically executed. In the function/script being executed, one or more
// of the following actions can be executed:
//  - load a file containing the referenced object. This function typically
//    looks in the file catalog (GRID).
//  - compute a pointer to the referenced object and communicate this pointer
//    back to the calling function TRef::GetObject via:
//      TRef::SetStaticObject(object).
//    When the TExec is called, it has access to the dereferencing TRef
//    by calling GetStaticObject() (TRef::GetObject() sets fgObject to "this"
//    before the call to TExec). This can be useful for accessing the TRef's
//    fUniqueID.
// As soon as an object is returned to GetObject, the fUniqueID of the TRef is set
// to the fUniqueID of the referenced object. At the next call to GetObject,
// the pointer stored in fPid:fObjects[fUniqueID] will be returned directly.
//
// An example of action on demand is shown in $ROOTSYS/test/Event.h with
// the member:
//      TRef    fWebHistogram;   //EXEC:GetWebHistogram
// When calling fWebHistogram.GetObject(), the function GetObject
// will automatically invoke a script GetWebHistogram.C via the interpreter.
// An example of a GetWebHistogram.C script is shown below
//    void GetWebHistogram() {
//       TFile *f= TFile::Open("http://root.cern.ch/files/pippa.root");
//       f->cd("DM/CJ");
//       TH1 *h6 = (TH1*)gDirectory->Get("h6");
//       h6->SetDirectory(0);
//       delete f;
//       TRef::SetStaticObject(h6);
//    }
// In the above example, a call to fWebHistogram.GetObject() executes the
// script with the function GetWebHistogram. This script connects a file
// with histograms: pippa.root on the ROOT Web site and returns the object h6
// to TRef::GetObject.
// Note that if the definition of the TRef fWebHistogram had been:
//      TRef    fWebHistogram;   //EXEC:GetWebHistogram()
// then, the compiled or interpreted function GetWebHistogram() would have
// been called instead of the CINT script GetWebHistogram.C
//
// Special case of a TRef pointing to an object with a TUUID
// ----------------------------------------------------------
// If the referenced object has a TUUID, its bit kHasUUID has been set.
// This case is detected by the TRef assignement operator.
// (For example, TFile and TDirectory have a TUUID)
// The TRef fPID points directly to the single object TProcessUUID (deriving
// from TProcessID) and managing the list of TUUIDs for a process.
// The TRef kHasUUID bit is set and its fUniqueID is set to the fUniqueID
// of the referenced object.
// When the TRef is streamed to a buffer, the corresponding TUUID is also
// streamed with the TRef. When a TRef is read from a buffer, the corresponding
// TUUID is also read and entered into the global list of TUUIDs (if not
// already there). The TRef fUniqueID is set to the UUIDNumber.
// see TProcessUUID for more details.
//
// Array of TRef
// -------------
// The special class TRefArray should be used to store multiple references.
// A TRefArray has one single pointer fPID for all objects in the array.
// It has a dynamic compact table of fUniqueIDs. Use a TRefArray rather
// then a collection of TRefs if all TRefs stem from the same process.
//
// Example:
// Suppose a TObjArray *mytracks containing a list of Track objects
// Suppose a TRefArray *pions containing pointers to the pion tracks in mytracks.
// This list is created with statements like: pions->Add(track);
// Suppose a TRefArray *muons containing pointers to the muon tracks in mytracks.
// The 3 arrays mytracks,pions and muons may be written separately.
//
//////////////////////////////////////////////////////////////////////////

#include "TRef.h"
#include "TROOT.h"
#include "TClass.h"
#include "TProcessUUID.h"
#include "TRefTable.h"
#include "TObjArray.h"
#include "TExec.h"
#include "TSystem.h"
#include "TObjString.h"

TObjArray  *TRef::fgExecs  = 0;
TObject    *TRef::fgObject = 0;

ClassImp(TRef)

//______________________________________________________________________________
TRef::TRef(TObject *obj)
{
   // Create a ref to obj.

   *this = obj;
}

//______________________________________________________________________________
TRef::TRef(const TRef &ref) : TObject(ref)
{
   // TRef copy ctor.

   *this = ref;
}

//______________________________________________________________________________
void TRef::operator=(TObject *obj)
{
   // Assign object to reference.

   UInt_t uid = 0;
   fPID = 0;
   if (obj) {
      if (obj->IsA()->CanIgnoreTObjectStreamer()) {
         Error("operator= ","Class: %s IgnoreTObjectStreamer. Cannot reference object",obj->ClassName());
         return;
      }
      if (obj->TestBit(kHasUUID)) {
         fPID = gROOT->GetUUIDs();
         obj->SetBit(kIsReferenced);
         SetBit(kHasUUID);
         uid = obj->GetUniqueID();
      } else {
         if (obj->TestBit(kIsReferenced)) {
            uid = obj->GetUniqueID();
            fPID = TProcessID::GetProcessWithUID(uid,obj);
         } else {
            fPID = TProcessID::GetSessionProcessID();
            uid = TProcessID::AssignID(obj);
         }
         ResetBit(kHasUUID);
      }
   }
   SetUniqueID(uid);
}

//______________________________________________________________________________
TRef &TRef::operator=(const TRef &ref)
{
   // TRef assignment operator.

   SetUniqueID(ref.GetUniqueID());
   fPID = ref.fPID;
   SetBit(kHasUUID,ref.TestBit(kHasUUID));
   return *this;
}

//______________________________________________________________________________
Bool_t operator==(const TRef &r1, const TRef &r2)
{
   // Return kTRUE if r1 and r2 point to the same object.

   if (r1.GetPID() == r2.GetPID() && r1.GetUniqueID() == r2.GetUniqueID()) return kTRUE;
   else return kFALSE;
}

//______________________________________________________________________________
Bool_t operator!=(const TRef &r1, const TRef &r2)
{
   // Return kTRUE if r1 and r2 do not point to the same object.

   if (r1.GetPID() == r2.GetPID() && r1.GetUniqueID() == r2.GetUniqueID()) return kFALSE;
   else return kTRUE;
}

//______________________________________________________________________________
Int_t TRef::AddExec(const char *name)
{
   // If Exec with name does not exist in the list of Execs, it is created.
   // returns the index of the Exec in the list.

   if (!fgExecs) fgExecs = new TObjArray(10);

   TExec *exec = (TExec*)fgExecs->FindObject(name);
   if (!exec) {
      // we register this Exec to the list of Execs.
      exec = new TExec(name,"");
      fgExecs->Add(exec);
   }
   return fgExecs->IndexOf(exec);
}

//______________________________________________________________________________
TObjArray *TRef::GetListOfExecs()
{
   // Return a pointer to the static TObjArray holding the list of Execs.

   if (!fgExecs) fgExecs = new TObjArray(10);

   return fgExecs;
}


//______________________________________________________________________________
TObject *TRef::GetObject() const
{
   // Return a pointer to the referenced object.

   //TObject *obj = 0;
   if (!fPID) return 0;
   if (!TProcessID::IsValid(fPID)) return 0;
   UInt_t uid = GetUniqueID();

   //the reference may be in the TRefTable
   TRefTable *table = TRefTable::GetRefTable();
   if (table) {
      table->SetUID(uid, fPID);
      table->Notify();
   }

   //Try to find the object from the table of the corresponding PID
   TObject *obj = fPID->GetObjectWithID(uid);

   //if object not found, then exec action if an action has been defined
   if (!obj) {
      //execid in the first 8 bits
      Int_t execid = TestBits(0xff0000);
      if (execid > 0) {
         execid = execid>>16;
         TExec *exec = (TExec*)fgExecs->At(execid-1);
         if (exec) {
            //we expect the object to be returned via TRef::SetStaticObject
            fgObject = const_cast<TRef*>(this);
            exec->Exec();
            if ((const TRef*)fgObject != this)
               obj = fgObject;
            else obj=0;
            if (obj){
               uid = TProcessID::AssignID(obj);
               ((TRef*)this)->SetUniqueID(uid);
               fPID->PutObjectWithID(obj,uid);
            } else {
               //well may be the Exec has loaded the object
               obj = fPID->GetObjectWithID(uid);
            }
         }
      }
   }

   return obj;
}

//______________________________________________________________________________
void TRef::SetAction(const char *name)
{
   // Store the exec number (in the ROOT list of Execs)
   // into the fBits of this TRef.

   TExec *exec = (TExec*)fgExecs->FindObject(name);
   if (!exec) {
      Error("SetAction","Unknow TExec: %s",name);
      return;
   }
   Int_t execid = 1 + fgExecs->IndexOf(exec);
   SetBit(execid << 8);
}

//______________________________________________________________________________
void TRef::SetAction(TObject *parent)
{
   // Find the action to be executed in the dictionary of the parent class
   // and store the corresponding exec number into fBits.
   // This function searches a data member in the class of parent with an
   // offset corresponding to this.
   // If a comment "TEXEC:" is found in the comment field of the data member,
   // the function stores the exec identifier of the exec statement
   // following this keyword.

   if (!parent) return;
   if (gDirectory) gDirectory->SetTRefAction(this,parent);
}

 //______________________________________________________________________________
TObject *TRef::GetStaticObject() {
   // Returns the static object.
   return fgObject;
}

//______________________________________________________________________________
void TRef::SetObject(TObject *obj)
{
   // static Obsolete function kept for back compatibility.
   // In the near future will print a Warning, then will be deleted.

   SetStaticObject(obj);
}

//______________________________________________________________________________
void TRef::SetStaticObject(TObject *obj)
{
   // Static function to set the object found on the Action on Demand function.
   // This function may be called by the user in the function called
   // when a "EXEC:" keyword is specified in the data member field of the TRef.
   // The function can get access to the dereferencing TRef (i.e. this)using
   // the static function GetStaticObject().

   fgObject = obj;
}

//______________________________________________________________________________
void TRef::Streamer(TBuffer &R__b)
{
   // Stream an object of class TRef.

   UShort_t pidf;
   if (R__b.IsReading()) {
      TObject::Streamer(R__b);
      if (TestBit(kHasUUID)) {
         TString s;
         s.Streamer(R__b);
         TProcessUUID *pid = gROOT->GetUUIDs();
         UInt_t number = pid->AddUUID(s.Data());
         fPID = pid;
         SetUniqueID(number);
         if (gDebug > 1) {
            printf("Reading TRef (HasUUID) uid=%d, obj=%lx\n",GetUniqueID(),(Long_t)GetObject());
         }
      } else {
         R__b >> pidf;
         pidf += R__b.GetPidOffset();
         fPID = R__b.ReadProcessID(pidf);
         //The execid has been saved in the unique id of the TStreamerElement
         //being read by TStreamerElement::Streamer
         //The current element (fgElement) is set as a static global
         //by TStreamerInfo::ReadBuffer (Clones) when reading this TRef
         Int_t execid = R__b.GetTRefExecId();
         if (execid) SetBit(execid<<16);
         if (gDebug > 1) {
            printf("Reading TRef, pidf=%d, fPID=%lx, uid=%d, obj=%lx\n",pidf,(Long_t)fPID,GetUniqueID(),(Long_t)GetObject());
         }
      }
   } else {
      TObject::Streamer(R__b);

      if (TestBit(kHasUUID)) {
         TObjString *objs = gROOT->GetUUIDs()->FindUUID(GetUniqueID());
         objs->String().Streamer(R__b);
         if (gDebug > 1) {
            printf("Writing TRef (HasUUID) uid=%d, obj=%lx\n",GetUniqueID(),(Long_t)GetObject());
         }
      } else {
         pidf = R__b.WriteProcessID(fPID);
         R__b << pidf;
         if (gDebug > 1) {
            printf("Writing TRef, pidf=%d, fPID=%lx, uid=%d, obj=%lx\n",pidf,(Long_t)fPID,GetUniqueID(),(Long_t)GetObject());
         }
      }
   }
}
 TRef.cxx:1
 TRef.cxx:2
 TRef.cxx:3
 TRef.cxx:4
 TRef.cxx:5
 TRef.cxx:6
 TRef.cxx:7
 TRef.cxx:8
 TRef.cxx:9
 TRef.cxx:10
 TRef.cxx:11
 TRef.cxx:12
 TRef.cxx:13
 TRef.cxx:14
 TRef.cxx:15
 TRef.cxx:16
 TRef.cxx:17
 TRef.cxx:18
 TRef.cxx:19
 TRef.cxx:20
 TRef.cxx:21
 TRef.cxx:22
 TRef.cxx:23
 TRef.cxx:24
 TRef.cxx:25
 TRef.cxx:26
 TRef.cxx:27
 TRef.cxx:28
 TRef.cxx:29
 TRef.cxx:30
 TRef.cxx:31
 TRef.cxx:32
 TRef.cxx:33
 TRef.cxx:34
 TRef.cxx:35
 TRef.cxx:36
 TRef.cxx:37
 TRef.cxx:38
 TRef.cxx:39
 TRef.cxx:40
 TRef.cxx:41
 TRef.cxx:42
 TRef.cxx:43
 TRef.cxx:44
 TRef.cxx:45
 TRef.cxx:46
 TRef.cxx:47
 TRef.cxx:48
 TRef.cxx:49
 TRef.cxx:50
 TRef.cxx:51
 TRef.cxx:52
 TRef.cxx:53
 TRef.cxx:54
 TRef.cxx:55
 TRef.cxx:56
 TRef.cxx:57
 TRef.cxx:58
 TRef.cxx:59
 TRef.cxx:60
 TRef.cxx:61
 TRef.cxx:62
 TRef.cxx:63
 TRef.cxx:64
 TRef.cxx:65
 TRef.cxx:66
 TRef.cxx:67
 TRef.cxx:68
 TRef.cxx:69
 TRef.cxx:70
 TRef.cxx:71
 TRef.cxx:72
 TRef.cxx:73
 TRef.cxx:74
 TRef.cxx:75
 TRef.cxx:76
 TRef.cxx:77
 TRef.cxx:78
 TRef.cxx:79
 TRef.cxx:80
 TRef.cxx:81
 TRef.cxx:82
 TRef.cxx:83
 TRef.cxx:84
 TRef.cxx:85
 TRef.cxx:86
 TRef.cxx:87
 TRef.cxx:88
 TRef.cxx:89
 TRef.cxx:90
 TRef.cxx:91
 TRef.cxx:92
 TRef.cxx:93
 TRef.cxx:94
 TRef.cxx:95
 TRef.cxx:96
 TRef.cxx:97
 TRef.cxx:98
 TRef.cxx:99
 TRef.cxx:100
 TRef.cxx:101
 TRef.cxx:102
 TRef.cxx:103
 TRef.cxx:104
 TRef.cxx:105
 TRef.cxx:106
 TRef.cxx:107
 TRef.cxx:108
 TRef.cxx:109
 TRef.cxx:110
 TRef.cxx:111
 TRef.cxx:112
 TRef.cxx:113
 TRef.cxx:114
 TRef.cxx:115
 TRef.cxx:116
 TRef.cxx:117
 TRef.cxx:118
 TRef.cxx:119
 TRef.cxx:120
 TRef.cxx:121
 TRef.cxx:122
 TRef.cxx:123
 TRef.cxx:124
 TRef.cxx:125
 TRef.cxx:126
 TRef.cxx:127
 TRef.cxx:128
 TRef.cxx:129
 TRef.cxx:130
 TRef.cxx:131
 TRef.cxx:132
 TRef.cxx:133
 TRef.cxx:134
 TRef.cxx:135
 TRef.cxx:136
 TRef.cxx:137
 TRef.cxx:138
 TRef.cxx:139
 TRef.cxx:140
 TRef.cxx:141
 TRef.cxx:142
 TRef.cxx:143
 TRef.cxx:144
 TRef.cxx:145
 TRef.cxx:146
 TRef.cxx:147
 TRef.cxx:148
 TRef.cxx:149
 TRef.cxx:150
 TRef.cxx:151
 TRef.cxx:152
 TRef.cxx:153
 TRef.cxx:154
 TRef.cxx:155
 TRef.cxx:156
 TRef.cxx:157
 TRef.cxx:158
 TRef.cxx:159
 TRef.cxx:160
 TRef.cxx:161
 TRef.cxx:162
 TRef.cxx:163
 TRef.cxx:164
 TRef.cxx:165
 TRef.cxx:166
 TRef.cxx:167
 TRef.cxx:168
 TRef.cxx:169
 TRef.cxx:170
 TRef.cxx:171
 TRef.cxx:172
 TRef.cxx:173
 TRef.cxx:174
 TRef.cxx:175
 TRef.cxx:176
 TRef.cxx:177
 TRef.cxx:178
 TRef.cxx:179
 TRef.cxx:180
 TRef.cxx:181
 TRef.cxx:182
 TRef.cxx:183
 TRef.cxx:184
 TRef.cxx:185
 TRef.cxx:186
 TRef.cxx:187
 TRef.cxx:188
 TRef.cxx:189
 TRef.cxx:190
 TRef.cxx:191
 TRef.cxx:192
 TRef.cxx:193
 TRef.cxx:194
 TRef.cxx:195
 TRef.cxx:196
 TRef.cxx:197
 TRef.cxx:198
 TRef.cxx:199
 TRef.cxx:200
 TRef.cxx:201
 TRef.cxx:202
 TRef.cxx:203
 TRef.cxx:204
 TRef.cxx:205
 TRef.cxx:206
 TRef.cxx:207
 TRef.cxx:208
 TRef.cxx:209
 TRef.cxx:210
 TRef.cxx:211
 TRef.cxx:212
 TRef.cxx:213
 TRef.cxx:214
 TRef.cxx:215
 TRef.cxx:216
 TRef.cxx:217
 TRef.cxx:218
 TRef.cxx:219
 TRef.cxx:220
 TRef.cxx:221
 TRef.cxx:222
 TRef.cxx:223
 TRef.cxx:224
 TRef.cxx:225
 TRef.cxx:226
 TRef.cxx:227
 TRef.cxx:228
 TRef.cxx:229
 TRef.cxx:230
 TRef.cxx:231
 TRef.cxx:232
 TRef.cxx:233
 TRef.cxx:234
 TRef.cxx:235
 TRef.cxx:236
 TRef.cxx:237
 TRef.cxx:238
 TRef.cxx:239
 TRef.cxx:240
 TRef.cxx:241
 TRef.cxx:242
 TRef.cxx:243
 TRef.cxx:244
 TRef.cxx:245
 TRef.cxx:246
 TRef.cxx:247
 TRef.cxx:248
 TRef.cxx:249
 TRef.cxx:250
 TRef.cxx:251
 TRef.cxx:252
 TRef.cxx:253
 TRef.cxx:254
 TRef.cxx:255
 TRef.cxx:256
 TRef.cxx:257
 TRef.cxx:258
 TRef.cxx:259
 TRef.cxx:260
 TRef.cxx:261
 TRef.cxx:262
 TRef.cxx:263
 TRef.cxx:264
 TRef.cxx:265
 TRef.cxx:266
 TRef.cxx:267
 TRef.cxx:268
 TRef.cxx:269
 TRef.cxx:270
 TRef.cxx:271
 TRef.cxx:272
 TRef.cxx:273
 TRef.cxx:274
 TRef.cxx:275
 TRef.cxx:276
 TRef.cxx:277
 TRef.cxx:278
 TRef.cxx:279
 TRef.cxx:280
 TRef.cxx:281
 TRef.cxx:282
 TRef.cxx:283
 TRef.cxx:284
 TRef.cxx:285
 TRef.cxx:286
 TRef.cxx:287
 TRef.cxx:288
 TRef.cxx:289
 TRef.cxx:290
 TRef.cxx:291
 TRef.cxx:292
 TRef.cxx:293
 TRef.cxx:294
 TRef.cxx:295
 TRef.cxx:296
 TRef.cxx:297
 TRef.cxx:298
 TRef.cxx:299
 TRef.cxx:300
 TRef.cxx:301
 TRef.cxx:302
 TRef.cxx:303
 TRef.cxx:304
 TRef.cxx:305
 TRef.cxx:306
 TRef.cxx:307
 TRef.cxx:308
 TRef.cxx:309
 TRef.cxx:310
 TRef.cxx:311
 TRef.cxx:312
 TRef.cxx:313
 TRef.cxx:314
 TRef.cxx:315
 TRef.cxx:316
 TRef.cxx:317
 TRef.cxx:318
 TRef.cxx:319
 TRef.cxx:320
 TRef.cxx:321
 TRef.cxx:322
 TRef.cxx:323
 TRef.cxx:324
 TRef.cxx:325
 TRef.cxx:326
 TRef.cxx:327
 TRef.cxx:328
 TRef.cxx:329
 TRef.cxx:330
 TRef.cxx:331
 TRef.cxx:332
 TRef.cxx:333
 TRef.cxx:334
 TRef.cxx:335
 TRef.cxx:336
 TRef.cxx:337
 TRef.cxx:338
 TRef.cxx:339
 TRef.cxx:340
 TRef.cxx:341
 TRef.cxx:342
 TRef.cxx:343
 TRef.cxx:344
 TRef.cxx:345
 TRef.cxx:346
 TRef.cxx:347
 TRef.cxx:348
 TRef.cxx:349
 TRef.cxx:350
 TRef.cxx:351
 TRef.cxx:352
 TRef.cxx:353
 TRef.cxx:354
 TRef.cxx:355
 TRef.cxx:356
 TRef.cxx:357
 TRef.cxx:358
 TRef.cxx:359
 TRef.cxx:360
 TRef.cxx:361
 TRef.cxx:362
 TRef.cxx:363
 TRef.cxx:364
 TRef.cxx:365
 TRef.cxx:366
 TRef.cxx:367
 TRef.cxx:368
 TRef.cxx:369
 TRef.cxx:370
 TRef.cxx:371
 TRef.cxx:372
 TRef.cxx:373
 TRef.cxx:374
 TRef.cxx:375
 TRef.cxx:376
 TRef.cxx:377
 TRef.cxx:378
 TRef.cxx:379
 TRef.cxx:380
 TRef.cxx:381
 TRef.cxx:382
 TRef.cxx:383
 TRef.cxx:384
 TRef.cxx:385
 TRef.cxx:386
 TRef.cxx:387
 TRef.cxx:388
 TRef.cxx:389
 TRef.cxx:390
 TRef.cxx:391
 TRef.cxx:392
 TRef.cxx:393
 TRef.cxx:394
 TRef.cxx:395
 TRef.cxx:396
 TRef.cxx:397
 TRef.cxx:398
 TRef.cxx:399
 TRef.cxx:400
 TRef.cxx:401
 TRef.cxx:402
 TRef.cxx:403
 TRef.cxx:404
 TRef.cxx:405
 TRef.cxx:406
 TRef.cxx:407
 TRef.cxx:408
 TRef.cxx:409
 TRef.cxx:410
 TRef.cxx:411
 TRef.cxx:412
 TRef.cxx:413
 TRef.cxx:414
 TRef.cxx:415
 TRef.cxx:416
 TRef.cxx:417
 TRef.cxx:418
 TRef.cxx:419
 TRef.cxx:420
 TRef.cxx:421
 TRef.cxx:422
 TRef.cxx:423
 TRef.cxx:424
 TRef.cxx:425
 TRef.cxx:426
 TRef.cxx:427
 TRef.cxx:428
 TRef.cxx:429
 TRef.cxx:430
 TRef.cxx:431
 TRef.cxx:432
 TRef.cxx:433
 TRef.cxx:434
 TRef.cxx:435
 TRef.cxx:436
 TRef.cxx:437
 TRef.cxx:438
 TRef.cxx:439
 TRef.cxx:440
 TRef.cxx:441
 TRef.cxx:442
 TRef.cxx:443
 TRef.cxx:444
 TRef.cxx:445
 TRef.cxx:446
 TRef.cxx:447
 TRef.cxx:448
 TRef.cxx:449
 TRef.cxx:450
 TRef.cxx:451
 TRef.cxx:452
 TRef.cxx:453
 TRef.cxx:454
 TRef.cxx:455
 TRef.cxx:456
 TRef.cxx:457
 TRef.cxx:458
 TRef.cxx:459
 TRef.cxx:460
 TRef.cxx:461
 TRef.cxx:462
 TRef.cxx:463
 TRef.cxx:464
 TRef.cxx:465
 TRef.cxx:466
 TRef.cxx:467
 TRef.cxx:468
 TRef.cxx:469
 TRef.cxx:470
 TRef.cxx:471
 TRef.cxx:472
 TRef.cxx:473
 TRef.cxx:474
 TRef.cxx:475
 TRef.cxx:476
 TRef.cxx:477
 TRef.cxx:478
 TRef.cxx:479