// @(#)root/meta:$Id$
// Author: Fons Rademakers   04/02/95

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//
//  TDataMember.
//
// All ROOT classes may have RTTI (run time type identification) support
// added. The data is stored in so called DICTIONARY (look at TDictionary).
// Information about a class is stored in TClass.
// This information may be obtained via the cling api - see class TCling.
// TClass has a list of TDataMember objects providing information about all
// data members of described class.
//Begin_Html
/*
<img align=center src="gif/classinfo.gif">
*/
//End_Html
// TDataMember provides information about name of data member, its type,
// and comment field string. It also tries to find the TMethodCall objects
// responsible for getting/setting a value of it, and gives you pointers
// to these methods. This gives you a unique possibility to access
// protected and private (!) data members if only methods for doing that
// are defined.
// These methods could either be specified in a comment field, or found
// out automatically by ROOT: here's an example:
// suppose you have a class definition:
//Begin_Html <pre>
/*

        class MyClass{
            private:
                Float_t fX1;
                    ...
            public:
                void    SetX1(Float_t x) {fX1 = x;};
                Float_t GetX1()          {return fX1;};
                    ...
        }

*/
//</pre>
//End_Html
// Look at the data member name and method names: a data member name has
// a prefix letter (f) and has a base name X1 . The methods for getting and
// setting this value have names which consist of string Get/Set and the
// same base name. This convention of naming data fields and methods which
// access them allows TDataMember find this methods by itself completely
// automatically. To make this description complete, one should know,
// that names that are automatically recognized may be also:
// for data fields: either fXXX or fIsXXX; and for getter function
// GetXXX() or IsXXX() [where XXX is base name].
//
// As an example of using it let's analyse a few lines which get and set
// a fEditable field in TCanvas:
//Begin_Html <pre>
/*

    TCanvas     *c  = new TCanvas("c");   // create a canvas
    TClass      *cl = c-&gt;IsA();            // get its class description object.

    TDataMember *dm = cl-&gt;GetDataMember("fEditable"); //This is our data member

    TMethodCall *getter = dm-&gt;GetterMethod(c); //find a method that gets value!
    Long_t l;   // declare a storage for this value;

    getter-&gt;Execute(c,"",l);  // Get this Value !!!! It will appear in l !!!


    TMethodCall *setter = dm-&gt;SetterMethod(c);
    setter-&gt;Execute(c,"0",);   // Set Value 0 !!!

*/
//</pre>
//End_Html
//
// This trick is widely used in ROOT TContextMenu and dialogs for obtaining
// current values and put them as initial values in dialog fields.
//
// If you don't want to follow the convention of naming used by ROOT
// you still could benefit from Getter/Setter method support: the solution
// is to instruct ROOT what the names of these routines are.
// The way to do it is putting this information in a comment string to a data
// field in your class declaration:
//
//Begin_Html <pre>
/*

    class MyClass{
        Int_t mydata;  // <em> *OPTIONS={GetMethod="Get";SetMethod="Set"} </em>
         ...
        Int_t Get() const { return mydata;};
        void  Set(Int_t i) {mydata=i;};
        }
*/
//</pre>
//End_Html
//
// However, this getting/setting functions are not the only feature of
// this class. The next point is providing lists of possible settings
// for the concerned data member. The idea is to have a list of possible
// options for this data member, with strings identifying them. This
// is used in dialogs with parameters to set - for details see
// TMethodArg, TRootContextMenu, TContextMenu. This list not only specifies
// the allowed value, but also provides strings naming the options.
// Options are managed via TList of TOptionListItem objects. This list
// is also  created automatically: if a data type is an enum tynpe,
// the list will have items describing every enum value, and named
// according to enum name. If type is Bool_t, two options "On" and "Off"
// with values 0 and 1 are created. For other types you need to instruct
// ROOT about possible options. The way to do it is the same as in case of
// specifying getter/setter method: a comment string to a data field in
// Your header file with class definition.
// The most general format of this string is:
//Begin_Html <pre>
/*

<em>*OPTIONS={GetMethod="</em>getter<em>";SetMethod="</em>setter<em>";Items=(</em>it1<em>="</em>title1<em>",</em>it2<em>="</em>title2<em>", ... ) } </em>

*/
//</pre>
//End_Html
//
// While parsing this string ROOT firstly looks for command-tokens:
// GetMethod, SetMethod, Items; They must be preceded by string
// *OPTIONS= , enclosed by {} and separated by semicolons ";".
// All command token should have a form TOKEN=VALUE.
// All tokens are optional.
// The names of getter and setter method must be enclosed by double-quote
// marks (") .
// Specifications of Items is slightly more complicated: you need to
// put token ITEMS= and then enclose all options in curly brackets "()".
// You separate options by comas ",".
// Each option item may have one of the following forms:
//Begin_Html <pre>
/*
         IntegerValue<em>  = "</em>Text Label<em>"</em>

         EnumValue   <em>  = "</em>Text Label<em>"</em>

        <em>"</em>TextValue<em>" = </em>Text Label<em>"</em>

*/
//</pre>
//End_Html
//
// One can sepcify values as Integers or Enums - when data field is an
// Integer, Float or Enum type; as texts - for char (more precisely:
// Option_t).
//
// As mentioned above - this information are mainly used by contextmenu,
// but also in Dump() and Inspect() methods and by the THtml class.
//
//////////////////////////////////////////////////////////////////////////

#include "TDataMember.h"

#include "Strlen.h"
#include "TClass.h"
#include "TClassEdit.h"
#include "TDataType.h"
#include "TEnum.h"
#include "TEnumConstant.h"
#include "TGlobal.h"
#include "TInterpreter.h"
#include "TIterator.h"
#include "TList.h"
#include "TListOfDataMembers.h"
#include "TMethod.h"
#include "TMethodCall.h"
#include "TRealData.h"
#include "TROOT.h"
#include "TVirtualMutex.h"

#include <stdlib.h>


ClassImp(TDataMember)

//______________________________________________________________________________
TDataMember::TDataMember(DataMemberInfo_t *info, TClass *cl) : TDictionary()
{
   // Default TDataMember ctor. TDataMembers are constructed in TClass
   // via a call to TCling::CreateListOfDataMembers(). It parses the comment
   // string, initializes optionlist and getter/setter methods.

   fInfo        = info;
   fClass       = cl;
   fDataType    = 0;
   fOptions     = 0;
   fValueSetter = 0;
   fValueGetter = 0;
   fOffset      = -1;
   fProperty    = -1;
   fSTLCont     = -1;
   fArrayDim    = -1;
   fArrayMaxIndex=0;
   if (!fInfo && !fClass) return; // default ctor is called

   Init(false);
}

//______________________________________________________________________________
void TDataMember::Init(bool afterReading)
{
   // Routines called by the constructor and Update to reset the member's
   // information.
   // afterReading is set when initializing after reading through Streamer().
   const char *t = 0;
   if (!afterReading) {
      // Initialize from fInfo
      if (!fInfo || !gInterpreter->DataMemberInfo_IsValid(fInfo)) return;

      fFullTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeName(fInfo));
      fTrueTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeTrueName(fInfo));
      fTypeName     = TClassEdit::GetLong64_Name(gCling->TypeName(fTrueTypeName));
      SetName(gCling->DataMemberInfo_Name(fInfo));
      t = gCling->DataMemberInfo_Title(fInfo);
      SetTitle(t);
   } else {
      // We have read the persistent data members.
      t = GetTitle();
   }
   if (t && t[0] != '!') SetBit(kObjIsPersistent);
   fDataType = 0;
   if (IsBasic() || IsEnum()) {
      if (IsBasic()) {
         const char *name = GetFullTypeName();
         if (strcmp(name, "unsigned char") != 0 &&
             strncmp(name, "unsigned short", sizeof ("unsigned short")) != 0 &&
             strcmp(name, "unsigned int") != 0 &&
             strncmp(name, "unsigned long", sizeof ("unsigned long")) != 0)
            // strncmp() also covers "unsigned long long"
            name = GetTypeName();
         fDataType = gROOT->GetType(name);

         if (fDataType==0) {
            // humm we did not find it ... maybe it's a typedef that has not been loaded yet.
            // (this can happen if the executable does not have a TApplication object).
            fDataType = gROOT->GetType(name,kTRUE);
         }
      } else {
         fDataType = gROOT->GetType("Int_t", kTRUE); // In rare instance we are called before Int_t has been added to the list of types in TROOT, the kTRUE insures it is there.
      }
      //         if (!fDataType)
      //            Error("TDataMember", "basic data type %s not found in list of basic types",
      //                  GetTypeName());
   }


   if (afterReading) {
      // Options are streamed; can't build TMethodCall for getters and setters
      // because we deserialize a TDataMember when we do not have interpreter
      // data. Thus do an early return.
      return;
   }


   // If option string exist in comment - we'll parse it and create
   // list of options

   // Option-list string has a form:
   // *OPTION={GetMethod="GetXXX";SetMethod="SetXXX";
   //          Items=(0="NULL ITEM","one"="First Item",kRed="Red Item")}
   //
   // As one can see it is possible to specify value as either numerical
   // value , string  or enum.
   // One can also specify implicitly names of Getter/Setter methods.

   char cmt[2048];
   char opt[2048];
   char *opt_ptr = 0;
   const char *ptr1    = 0;
   char *ptr2    = 0;
   char *ptr3    = 0;
   char *tok     = 0;
   Int_t cnt     = 0;
   Int_t token_cnt;
   Int_t i;

   strlcpy(cmt,GetTitle(),2048);

   if ((opt_ptr=strstr(cmt,"*OPTION={"))) {

      // If we found it - parsing...

      //let's cut the part lying between {}
      ptr1 = strtok(opt_ptr  ,"{}");  //starts tokenizing:extracts "*OPTION={"
      if (ptr1 == 0) {
         Fatal("TDataMember","Internal error, found \"*OPTION={\" but not \"{}\" in %s.",GetTitle());
         return;
      }
      ptr1 = strtok((char*)0,"{}");   //And now we have what we need in ptr1!!!
      if (ptr1 == 0) {
         Fatal("TDataMember","Internal error, found \"*OPTION={\" but not \"{}\" in %s.",GetTitle());
         return;
      }

      //and save it:
      strlcpy(opt,ptr1,2048);

      // Let's extract sub-tokens extracted by ';' sign.
      // We'll put'em in an array for convenience;
      // You have to do it in this manner because you cannot use nested 'strtok'

      char *tokens[256];           // a storage for these sub-tokens.
      token_cnt = 0;
      cnt       = 0;

      do {                          //tokenizing loop
         ptr1=strtok((char*) (cnt++ ? 0:opt),";");
         if (ptr1){
            Int_t nch = strlen(ptr1)+1;
            tok=new char[nch];
            strlcpy(tok,ptr1,nch);
            tokens[token_cnt]=tok;
            token_cnt++;
         }
      } while (ptr1);

      // OK! Now let's check whether we have Get/Set methods encode in any string
      for (i=0;i<token_cnt;i++) {

         if (strstr(tokens[i],"GetMethod")) {
            ptr1 = strtok(tokens[i],"\"");    //tokenizing-strip text "GetMethod"
            if (ptr1 == 0) {
               Fatal("TDataMember","Internal error, found \"GetMethod\" but not \"\\\"\" in %s.",GetTitle());
               return;
            }
            ptr1 = strtok(0,"\"");         //tokenizing - name is in ptr1!
            if (ptr1 == 0) {
               Fatal("TDataMember","Internal error, found \"GetMethod\" but not \"\\\"\" in %s.",GetTitle());
               return;
            }

            if (!afterReading &&  GetClass()->GetMethod(ptr1,"")) // check whether such method exists
               // FIXME: wrong in case called derives via multiple inheritance from this class
               fValueGetter = new TMethodCall(GetClass(),ptr1,"");

            continue; //next item!
         }

         if (strstr(tokens[i],"SetMethod")) {
            ptr1 = strtok(tokens[i],"\"");
            if (ptr1 == 0) {
               Fatal("TDataMember","Internal error, found \"SetMethod\" but not \"\\\"\" in %s.",GetTitle());
               return;
            }
            ptr1 = strtok((char*)0,"\"");    //name of Setter in ptr1
            if (ptr1 == 0) {
               Fatal("TDataMember","Internal error, found \"SetMethod\" but not \"\\\"\" in %s.",GetTitle());
               return;
            }
            if (GetClass()->GetMethod(ptr1,"1"))
               // FIXME: wrong in case called derives via multiple inheritance from this class
               fValueSetter = new TMethodCall(GetClass(),ptr1,"1");
         }
      }

      //Now let's parse option strings...

      Int_t  opt_cnt    = 0;
      TList *optionlist = new TList();       //storage for options strings

      for (i=0;i<token_cnt;i++) {
         if (strstr(tokens[i],"Items")) {
            ptr1 = strtok(tokens[i],"()");
            if (ptr1 == 0) {
               Fatal("TDataMember","Internal error, found \"Items\" but not \"()\" in %s.",GetTitle());
               return;
            }
            ptr1 = strtok((char*)0,"()");
            if (ptr1 == 0) {
               Fatal("TDataMember","Internal error, found \"Items\" but not \"()\" in %s.",GetTitle());
               return;
            }

            char opts[2048];  //and save it!
            strlcpy(opts,ptr1,2048);

            //now parse it...
            //fistly we just store strings like: xxx="Label Name"
            //We'll store it in TOptionListItem objects, because they're derived
            //from TObject and thus can be stored in TList.
            //It's not elegant but works.

            do {
               ptr1 = strtok(opt_cnt++ ? (char*)0:opts,","); //options extraction
               if (ptr1) {
                  TOptionListItem *it = new TOptionListItem(this,1,0,0,ptr1,"");
                  optionlist->Add(it);
               }
            } while(ptr1);

         }
      }

      //having all options extracted and put into list, we finally can parse
      //them to create a list of options...

      fOptions = new TList();                //create the list

      TIter next(optionlist);                //we'll iterate through all
                                             //strings containing options
      TOptionListItem *it  = 0;
      TOptionListItem *it1 = 0;
      while ((it=(TOptionListItem*)next())) {

         ptr1 = it->fOptName;  // We will change the value of OptName ... but it is fine since we delete the object at the end of the loop.
         Bool_t islabel = (ptr1[0]=='\"');   // value is label or numerical?
         ptr2 = strtok((char*)ptr1,"=\"");   //extract LeftHandeSide
         ptr3 = strtok(0,"=\"");             //extract RightHandedSize

         if (islabel) {
            it1=new TOptionListItem(this,-9999,0,0,ptr3,ptr2);
            fOptions->Add(it1);
         }  else {
            //We'll try to find global enum existing in ROOT...
            Long_t l=0;
            Int_t  *value;
            TGlobal *enumval = gROOT->GetGlobal(ptr1,kTRUE);
            if (enumval){
               value = (Int_t*)(enumval->GetAddress());
               l     = (Long_t)(*value);
            } else if (IsEnum()) {
               TObject *obj = fClass->GetListOfDataMembers(false)->FindObject(ptr1);
               if (obj)
                  l = ((TEnumConstant*)obj)->GetValue();
               else
                  l = gInterpreter->Calc(Form("%s;",ptr1));
            } else
               l = atol(ptr1);

            it1 = new TOptionListItem(this,l,0,0,ptr3,ptr1);
            fOptions->Add(it1);
         }

         optionlist->Remove(it);         //delete this option string from list
         delete it;                      // and dispose of it.

      }

      // Garbage colletion

      // dispose of temporary option list...
      delete optionlist;

      //And dispose tokens string...
      for (i=0;i<token_cnt;i++) if(tokens[i]) delete [] tokens[i];

   // if option string does not exist but it's an Enum - parse it!!!!
   } else if (IsEnum()) {
      fOptions = new TList();
      if (TEnum* enumDict = TEnum::GetEnum(GetTypeName()) ){
         TIter iEnumConst(enumDict->GetConstants());
         while (TEnumConstant* enumConst = (TEnumConstant*)iEnumConst()) {
            TOptionListItem *it
               = new TOptionListItem(this, enumConst->GetValue(),0,0,
                                     enumConst->GetName(),enumConst->GetName());
            fOptions->Add(it);
         }
      }

   // and the case od Bool_t : we add items "ON" and "Off"
   } else if (!strncmp(GetFullTypeName(),"Bool_t",6)){

      fOptions = new TList();
      TOptionListItem *it = new TOptionListItem(this,1,0,0,"ON",0);
      fOptions->Add(it);
      it = new TOptionListItem(this,0,0,0,"Off",0);
      fOptions->Add(it);

   } else fOptions = 0;

}

//______________________________________________________________________________
TDataMember::TDataMember(const TDataMember& dm) :
  TDictionary(dm),
  fInfo(gCling->DataMemberInfo_FactoryCopy(dm.fInfo)),
  fClass(dm.fClass),
  fDataType(dm.fDataType),
  fOffset(dm.fOffset),
  fSTLCont(dm.fSTLCont),
  fProperty(dm.fProperty),
  fArrayDim(dm.fArrayDim),
  fArrayMaxIndex( dm.fArrayDim ? new Int_t[dm.fArrayDim] : 0),
  fArrayIndex(dm.fArrayIndex),
  fTypeName(dm.fTypeName),
  fFullTypeName(dm.fFullTypeName),
  fTrueTypeName(dm.fTrueTypeName),
  fValueGetter(0),
  fValueSetter(0),
  fOptions(dm.fOptions ? (TList*)dm.fOptions->Clone() : 0)
{
   //copy constructor
   for(Int_t d = 0; d < fArrayDim; ++d)
      fArrayMaxIndex[d] = dm.fArrayMaxIndex[d];
}

//______________________________________________________________________________
TDataMember& TDataMember::operator=(const TDataMember& dm)
{
   //assignement operator
   if(this!=&dm) {
      gCling->DataMemberInfo_Delete(fInfo);
      delete fValueSetter;
      delete fValueGetter;
      if (fOptions) {
         fOptions->Delete();
         delete fOptions;
         fOptions = 0;
      }

      TDictionary::operator=(dm);
      fInfo= gCling->DataMemberInfo_FactoryCopy(dm.fInfo);
      fClass=dm.fClass;
      fDataType=dm.fDataType;
      fOffset=dm.fOffset;
      fSTLCont=dm.fSTLCont;
      fProperty=dm.fProperty;
      fArrayDim = dm.fArrayDim;
      fArrayMaxIndex = dm.fArrayDim ? new Int_t[dm.fArrayDim] : 0;
      for(Int_t d = 0; d < fArrayDim; ++d)
         fArrayMaxIndex[d] = dm.fArrayMaxIndex[d];
      fArrayIndex = dm.fArrayIndex;
      fTypeName=dm.fTypeName;
      fFullTypeName=dm.fFullTypeName;
      fTrueTypeName=dm.fTrueTypeName;
      fOptions = dm.fOptions ? (TList*)dm.fOptions->Clone() : 0;
   }
   return *this;
}

//______________________________________________________________________________
TDataMember::~TDataMember()
{
   // TDataMember dtor deletes adopted CINT DataMemberInfo object.

   delete [] fArrayMaxIndex;
   gCling->DataMemberInfo_Delete(fInfo);
   delete fValueSetter;
   delete fValueGetter;
   if (fOptions) {
      fOptions->Delete();
      delete fOptions;
   }
}

//______________________________________________________________________________
Int_t TDataMember::GetArrayDim() const
{
   // Return number of array dimensions.

   if (fArrayDim<0 && fInfo) {
      R__LOCKGUARD(gInterpreterMutex);
      TDataMember *dm = const_cast<TDataMember*>(this);
      dm->fArrayDim = gCling->DataMemberInfo_ArrayDim(fInfo);
      // fArrayMaxIndex should be zero
      if (dm->fArrayDim) {
         dm->fArrayMaxIndex = new Int_t[fArrayDim];
         for(Int_t dim = 0; dim < fArrayDim; ++dim) {
            dm->fArrayMaxIndex[dim] = gCling->DataMemberInfo_MaxIndex(fInfo,dim);
         }
      }
   }
   return fArrayDim;
}

//______________________________________________________________________________
const char *TDataMember::GetArrayIndex() const
{
   // If the data member is pointer and has a valid array size in its comments
   // GetArrayIndex returns a string pointing to it;
   // otherwise it returns an empty string.

   if (!IsaPointer()) return "";
   if (fArrayIndex.Length()==0 && fInfo) {
      R__LOCKGUARD(gInterpreterMutex);
      TDataMember *dm = const_cast<TDataMember*>(this);
      const char* val = gCling->DataMemberInfo_ValidArrayIndex(fInfo);
      if (val) dm->fArrayIndex = val;
      else dm->fArrayIndex.Append((Char_t)0); // Make length non-zero but string still empty.
   }
   return fArrayIndex;
}

//______________________________________________________________________________
TDictionary::DeclId_t TDataMember::GetDeclId() const
{
   if (fInfo) return gInterpreter->GetDeclId(fInfo);
   else return 0;
}

//______________________________________________________________________________
Int_t TDataMember::GetMaxIndex(Int_t dim) const
{
   // Return maximum index for array dimension "dim".

   if (fArrayDim<0 && fInfo) {
      return gCling->DataMemberInfo_MaxIndex(fInfo,dim);
   } else {
      if (dim < 0 || dim >= fArrayDim) return -1;
      return fArrayMaxIndex[dim];
   }
}

//______________________________________________________________________________
const char *TDataMember::GetTypeName() const
{
   // Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".

   if (fProperty==(-1)) Property();
   return fTypeName.Data();
}

//______________________________________________________________________________
const char *TDataMember::GetFullTypeName() const
{
   // Get full type description of data member, e,g.: "class TDirectory*".
   if (fProperty==(-1)) Property();

   return fFullTypeName.Data();
}

//______________________________________________________________________________
const char *TDataMember::GetTrueTypeName() const
{
   // Get full type description of data member, e,g.: "class TDirectory*".

   return fTrueTypeName.Data();
}

//______________________________________________________________________________
Long_t TDataMember::GetOffset() const
{
   // Get offset from "this".

   if (fOffset>=0) return fOffset;

   R__LOCKGUARD(gInterpreterMutex);
   //case of an interpreted or emulated class
   if (fClass->GetDeclFileLine() < 0) {
      ((TDataMember*)this)->fOffset = gCling->DataMemberInfo_Offset(fInfo);
      return fOffset;
   }
   //case of a compiled class
   //Note that the offset cannot be computed in case of an abstract class
   //for which the list of real data has not yet been computed via
   //a real daughter class.
   TString dmbracket;
   dmbracket.Form("%s[",GetName());
   fClass->BuildRealData();
   TIter next(fClass->GetListOfRealData());
   TRealData *rdm;
   Int_t offset = 0;
   while ((rdm = (TRealData*)next())) {
      char *rdmc = (char*)rdm->GetName();
      //next statement required in case a class and one of its parent class
      //have data members with the same name
      if (this->IsaPointer() && rdmc[0] == '*') rdmc++;

      if (rdm->GetDataMember() != this) continue;
      if (strcmp(rdmc,GetName()) == 0) {
         offset = rdm->GetThisOffset();
         break;
      }
      if (strcmp(rdm->GetName(),GetName()) == 0) {
         if (rdm->IsObject()) {
            offset = rdm->GetThisOffset();
            break;
         }
      }
      if (strstr(rdm->GetName(),dmbracket.Data())) {
         offset = rdm->GetThisOffset();
         break;
      }
   }
   ((TDataMember*)this)->fOffset = offset;
   return fOffset;
}

//______________________________________________________________________________
Long_t TDataMember::GetOffsetCint() const
{
   // Get offset from "this" using the information in CINT only.

   if (fOffset>=0) return fOffset;

   R__LOCKGUARD(gInterpreterMutex);
   TDataMember *dm = const_cast<TDataMember*>(this);

   if (dm->IsValid()) return gCling->DataMemberInfo_Offset(dm->fInfo);
   else return -1;
}

//______________________________________________________________________________
Int_t TDataMember::GetUnitSize() const
{
   // Get the sizeof the underlying type of the data member
   // (i.e. if the member is an array sizeof(member)/length)

   if (IsaPointer()) return sizeof(void*);
   if (IsEnum()    ) return sizeof(Int_t);
   if (IsBasic()   ) return GetDataType()->Size();

   TClass *cl = TClass::GetClass(GetTypeName());
   if (!cl) cl = TClass::GetClass(GetTrueTypeName());
   if ( cl) return cl->Size();

   Warning("GetUnitSize","Can not determine sizeof(%s)",GetTypeName());
   return 0;
}

//______________________________________________________________________________
Bool_t TDataMember::IsBasic() const
{
   // Return true if data member is a basic type, e.g. char, int, long...

   if (fProperty == -1) Property();
   return (fProperty & kIsFundamental) ? kTRUE : kFALSE;
}

//______________________________________________________________________________
Bool_t TDataMember::IsEnum() const
{
   // Return true if data member is an enum.

   if (fProperty == -1) Property();
   return (fProperty & kIsEnum) ? kTRUE : kFALSE;
}

//______________________________________________________________________________
Bool_t TDataMember::IsaPointer() const
{
   // Return true if data member is a pointer.

   if (fProperty == -1) Property();
   return (fProperty & kIsPointer) ? kTRUE : kFALSE;
}

//______________________________________________________________________________
int TDataMember::IsSTLContainer()
{
   // The return type is defined in TDictionary (kVector, kList, etc.)

   if (fSTLCont != -1) return fSTLCont;
   R__LOCKGUARD(gInterpreterMutex);
   fSTLCont = TClassEdit::UnderlyingIsSTLCont(GetTrueTypeName());
   return fSTLCont;
}

//______________________________________________________________________________
Bool_t TDataMember::IsValid()
{
   // Return true if this data member object is pointing to a currently
   // loaded data member.  If a function is unloaded after the TDataMember
   // is created, the TDataMember will be set to be invalid.

   if (fOffset >= 0) return kTRUE;

   // Register the transaction when checking the validity of the object.
   if (!fInfo && UpdateInterpreterStateMarker()) {
      DeclId_t newId = gInterpreter->GetDataMember(fClass->GetClassInfo(), fName);
      if (newId) {
         DataMemberInfo_t *info
            = gInterpreter->DataMemberInfo_Factory(newId, fClass->GetClassInfo());
         Update(info);
         // We need to make sure that the list of data member is properly
         // informed and updated.
         TListOfDataMembers *lst = dynamic_cast<TListOfDataMembers*>(fClass->GetListOfDataMembers());
         lst->Update(this);
      }
      return newId != 0;
   }
   return fInfo != 0;
}

//______________________________________________________________________________
Long_t TDataMember::Property() const
{
   // Get property description word. For meaning of bits see EProperty.

   if (fProperty!=(-1)) return fProperty;

   R__LOCKGUARD(gInterpreterMutex);
   TDataMember *t = (TDataMember*)this;

   if (!fInfo || !gCling->DataMemberInfo_IsValid(fInfo)) return 0;
   int prop  = gCling->DataMemberInfo_Property(fInfo);
   int propt = gCling->DataMemberInfo_TypeProperty(fInfo);
   t->fProperty = prop|propt;

   t->fFullTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeName(fInfo));
   t->fTrueTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeTrueName(fInfo));
   t->fTypeName     = TClassEdit::GetLong64_Name(gCling->TypeName(fTrueTypeName));

   t->fName  = gCling->DataMemberInfo_Name(fInfo);
   t->fTitle = gCling->DataMemberInfo_Title(fInfo);

   return fProperty;
}

//______________________________________________________________________________
TList *TDataMember::GetOptions() const
{
   // Returns list of options - list of TOptionListItems

   return fOptions;
}

//______________________________________________________________________________
TMethodCall *TDataMember::GetterMethod(TClass *cl)
{
   // Return a TMethodCall method responsible for getting the value
   // of data member. The cl argument specifies the class of the object
   // which will be used to call this method (in case of multiple
   // inheritance TMethodCall needs to know this to calculate the proper
   // offset).

   if (!fValueGetter || cl) {

      R__LOCKGUARD(gInterpreterMutex);

      if (!cl) cl = fClass;

      if (fValueGetter) {
         TString methodname = fValueGetter->GetMethodName();
         delete fValueGetter;
         fValueGetter = new TMethodCall(cl, methodname.Data(), "");

      } else {
         // try to guess Getter function:
         // we strip the fist character of name of data field ('f') and then
         // try to find the name of Getter by applying "Get", "Is" or "Has"
         // as a prefix

         const char *dataname = GetName();

         TString gettername;
         gettername.Form( "Get%s", dataname+1);
         if (GetClass()->GetMethod(gettername, ""))
            return fValueGetter = new TMethodCall(cl, gettername, "");
         gettername.Form( "Is%s", dataname+1);
         if (GetClass()->GetMethod(gettername, ""))
            return fValueGetter = new TMethodCall(cl, gettername, "");
         gettername.Form( "Has%s", dataname+1);
         if (GetClass()->GetMethod(gettername, ""))
            return fValueGetter = new TMethodCall(cl, gettername, "");
      }
   }

   return fValueGetter;
}

//______________________________________________________________________________
TMethodCall *TDataMember::SetterMethod(TClass *cl)
{
   // Return a TMethodCall method responsible for setting the value
   // of data member. The cl argument specifies the class of the object
   // which will be used to call this method (in case of multiple
   // inheritance TMethodCall needs to know this to calculate the proper
   // offset).

   if (!fValueSetter || cl) {

      R__LOCKGUARD(gInterpreterMutex);

      if (!cl) cl = fClass;

      if (fValueSetter) {

         TString methodname = fValueSetter->GetMethodName();
         TString params = fValueSetter->GetParams();
         delete fValueSetter;
         fValueSetter = new TMethodCall(cl, methodname.Data(), params.Data());

      } else {

         // try to guess Setter function:
         // we strip the fist character of name of data field ('f') and then
         // try to find the name of Setter by applying "Set" as a prefix

         const char *dataname = GetName();

         TString settername;
         settername.Form( "Set%s", dataname+1);
         if (strstr(settername, "Is")) settername.Form( "Set%s", dataname+3);
         if (GetClass()->GetMethod(settername, "1"))
            fValueSetter = new TMethodCall(cl, settername, "1");
         if (!fValueSetter)
            if (GetClass()->GetMethod(settername, "true"))
               fValueSetter = new TMethodCall(cl, settername, "true");
      }
   }

   return fValueSetter;
}

//______________________________________________________________________________
Bool_t TDataMember::Update(DataMemberInfo_t *info)
{
   // Update the TFunction to reflect the new info.
   //
   // This can be used to implement unloading (info == 0) and then reloading
   // (info being the 'new' decl address).

   R__LOCKGUARD(gInterpreterMutex);

   if (fInfo) gCling->DataMemberInfo_Delete(fInfo);
   SafeDelete(fValueSetter);
   SafeDelete(fValueGetter);
   if (fOptions) {
      fOptions->Delete();
      SafeDelete(fOptions);
   }

   if (info == 0) {
      fOffset      = -1;
      fProperty    = -1;
      fSTLCont     = -1;
      fArrayDim    = -1;
      delete [] fArrayMaxIndex;
      fArrayMaxIndex=0;
      fArrayIndex.Clear();

      fInfo = 0;
      return kTRUE;
   } else {
      fInfo = info;
      Init(false);
      return kTRUE;
   }
}


//______________________________________________________________________________
void TDataMember::Streamer(TBuffer& b) {
   // Stream an object of TDataMember. Forces calculation of all cached
   // (and persistent) values.
   if (b.IsReading()) {
      b.ReadClassBuffer(Class(), this);
      Init(true /*reading*/);
   } else {
      // Writing.
      if (fProperty & kIsStatic) {
         // We have a static member and in this case fOffset contains the
         // actual address in memory of the data, it will be different everytime,
         // let's not record it.
         fOffset = -1;
      } else {
         GetOffset();
      }
      IsSTLContainer();
      GetArrayDim();
      GetArrayIndex();
      Property(); // also calculates fTypeName and friends
      b.WriteClassBuffer(Class(), this);
   }
}

//______________________________________________________________________________
TOptionListItem::TOptionListItem(TDataMember *d, Long_t val, Long_t valmask,
                 Long_t tglmask,const char *name, const char *label)
{
   // Constuctor.

   fDataMember    = d;
   fValue         = val;
   fValueMaskBit  = valmask;
   fToggleMaskBit = tglmask;
   if (name) {
      fOptName = name;
   }

   if(label) {
      fOptLabel = fOptLabel;
   }
}
 TDataMember.cxx:1
 TDataMember.cxx:2
 TDataMember.cxx:3
 TDataMember.cxx:4
 TDataMember.cxx:5
 TDataMember.cxx:6
 TDataMember.cxx:7
 TDataMember.cxx:8
 TDataMember.cxx:9
 TDataMember.cxx:10
 TDataMember.cxx:11
 TDataMember.cxx:12
 TDataMember.cxx:13
 TDataMember.cxx:14
 TDataMember.cxx:15
 TDataMember.cxx:16
 TDataMember.cxx:17
 TDataMember.cxx:18
 TDataMember.cxx:19
 TDataMember.cxx:20
 TDataMember.cxx:21
 TDataMember.cxx:22
 TDataMember.cxx:23
 TDataMember.cxx:24
 TDataMember.cxx:25
 TDataMember.cxx:26
 TDataMember.cxx:27
 TDataMember.cxx:28
 TDataMember.cxx:29
 TDataMember.cxx:30
 TDataMember.cxx:31
 TDataMember.cxx:32
 TDataMember.cxx:33
 TDataMember.cxx:34
 TDataMember.cxx:35
 TDataMember.cxx:36
 TDataMember.cxx:37
 TDataMember.cxx:38
 TDataMember.cxx:39
 TDataMember.cxx:40
 TDataMember.cxx:41
 TDataMember.cxx:42
 TDataMember.cxx:43
 TDataMember.cxx:44
 TDataMember.cxx:45
 TDataMember.cxx:46
 TDataMember.cxx:47
 TDataMember.cxx:48
 TDataMember.cxx:49
 TDataMember.cxx:50
 TDataMember.cxx:51
 TDataMember.cxx:52
 TDataMember.cxx:53
 TDataMember.cxx:54
 TDataMember.cxx:55
 TDataMember.cxx:56
 TDataMember.cxx:57
 TDataMember.cxx:58
 TDataMember.cxx:59
 TDataMember.cxx:60
 TDataMember.cxx:61
 TDataMember.cxx:62
 TDataMember.cxx:63
 TDataMember.cxx:64
 TDataMember.cxx:65
 TDataMember.cxx:66
 TDataMember.cxx:67
 TDataMember.cxx:68
 TDataMember.cxx:69
 TDataMember.cxx:70
 TDataMember.cxx:71
 TDataMember.cxx:72
 TDataMember.cxx:73
 TDataMember.cxx:74
 TDataMember.cxx:75
 TDataMember.cxx:76
 TDataMember.cxx:77
 TDataMember.cxx:78
 TDataMember.cxx:79
 TDataMember.cxx:80
 TDataMember.cxx:81
 TDataMember.cxx:82
 TDataMember.cxx:83
 TDataMember.cxx:84
 TDataMember.cxx:85
 TDataMember.cxx:86
 TDataMember.cxx:87
 TDataMember.cxx:88
 TDataMember.cxx:89
 TDataMember.cxx:90
 TDataMember.cxx:91
 TDataMember.cxx:92
 TDataMember.cxx:93
 TDataMember.cxx:94
 TDataMember.cxx:95
 TDataMember.cxx:96
 TDataMember.cxx:97
 TDataMember.cxx:98
 TDataMember.cxx:99
 TDataMember.cxx:100
 TDataMember.cxx:101
 TDataMember.cxx:102
 TDataMember.cxx:103
 TDataMember.cxx:104
 TDataMember.cxx:105
 TDataMember.cxx:106
 TDataMember.cxx:107
 TDataMember.cxx:108
 TDataMember.cxx:109
 TDataMember.cxx:110
 TDataMember.cxx:111
 TDataMember.cxx:112
 TDataMember.cxx:113
 TDataMember.cxx:114
 TDataMember.cxx:115
 TDataMember.cxx:116
 TDataMember.cxx:117
 TDataMember.cxx:118
 TDataMember.cxx:119
 TDataMember.cxx:120
 TDataMember.cxx:121
 TDataMember.cxx:122
 TDataMember.cxx:123
 TDataMember.cxx:124
 TDataMember.cxx:125
 TDataMember.cxx:126
 TDataMember.cxx:127
 TDataMember.cxx:128
 TDataMember.cxx:129
 TDataMember.cxx:130
 TDataMember.cxx:131
 TDataMember.cxx:132
 TDataMember.cxx:133
 TDataMember.cxx:134
 TDataMember.cxx:135
 TDataMember.cxx:136
 TDataMember.cxx:137
 TDataMember.cxx:138
 TDataMember.cxx:139
 TDataMember.cxx:140
 TDataMember.cxx:141
 TDataMember.cxx:142
 TDataMember.cxx:143
 TDataMember.cxx:144
 TDataMember.cxx:145
 TDataMember.cxx:146
 TDataMember.cxx:147
 TDataMember.cxx:148
 TDataMember.cxx:149
 TDataMember.cxx:150
 TDataMember.cxx:151
 TDataMember.cxx:152
 TDataMember.cxx:153
 TDataMember.cxx:154
 TDataMember.cxx:155
 TDataMember.cxx:156
 TDataMember.cxx:157
 TDataMember.cxx:158
 TDataMember.cxx:159
 TDataMember.cxx:160
 TDataMember.cxx:161
 TDataMember.cxx:162
 TDataMember.cxx:163
 TDataMember.cxx:164
 TDataMember.cxx:165
 TDataMember.cxx:166
 TDataMember.cxx:167
 TDataMember.cxx:168
 TDataMember.cxx:169
 TDataMember.cxx:170
 TDataMember.cxx:171
 TDataMember.cxx:172
 TDataMember.cxx:173
 TDataMember.cxx:174
 TDataMember.cxx:175
 TDataMember.cxx:176
 TDataMember.cxx:177
 TDataMember.cxx:178
 TDataMember.cxx:179
 TDataMember.cxx:180
 TDataMember.cxx:181
 TDataMember.cxx:182
 TDataMember.cxx:183
 TDataMember.cxx:184
 TDataMember.cxx:185
 TDataMember.cxx:186
 TDataMember.cxx:187
 TDataMember.cxx:188
 TDataMember.cxx:189
 TDataMember.cxx:190
 TDataMember.cxx:191
 TDataMember.cxx:192
 TDataMember.cxx:193
 TDataMember.cxx:194
 TDataMember.cxx:195
 TDataMember.cxx:196
 TDataMember.cxx:197
 TDataMember.cxx:198
 TDataMember.cxx:199
 TDataMember.cxx:200
 TDataMember.cxx:201
 TDataMember.cxx:202
 TDataMember.cxx:203
 TDataMember.cxx:204
 TDataMember.cxx:205
 TDataMember.cxx:206
 TDataMember.cxx:207
 TDataMember.cxx:208
 TDataMember.cxx:209
 TDataMember.cxx:210
 TDataMember.cxx:211
 TDataMember.cxx:212
 TDataMember.cxx:213
 TDataMember.cxx:214
 TDataMember.cxx:215
 TDataMember.cxx:216
 TDataMember.cxx:217
 TDataMember.cxx:218
 TDataMember.cxx:219
 TDataMember.cxx:220
 TDataMember.cxx:221
 TDataMember.cxx:222
 TDataMember.cxx:223
 TDataMember.cxx:224
 TDataMember.cxx:225
 TDataMember.cxx:226
 TDataMember.cxx:227
 TDataMember.cxx:228
 TDataMember.cxx:229
 TDataMember.cxx:230
 TDataMember.cxx:231
 TDataMember.cxx:232
 TDataMember.cxx:233
 TDataMember.cxx:234
 TDataMember.cxx:235
 TDataMember.cxx:236
 TDataMember.cxx:237
 TDataMember.cxx:238
 TDataMember.cxx:239
 TDataMember.cxx:240
 TDataMember.cxx:241
 TDataMember.cxx:242
 TDataMember.cxx:243
 TDataMember.cxx:244
 TDataMember.cxx:245
 TDataMember.cxx:246
 TDataMember.cxx:247
 TDataMember.cxx:248
 TDataMember.cxx:249
 TDataMember.cxx:250
 TDataMember.cxx:251
 TDataMember.cxx:252
 TDataMember.cxx:253
 TDataMember.cxx:254
 TDataMember.cxx:255
 TDataMember.cxx:256
 TDataMember.cxx:257
 TDataMember.cxx:258
 TDataMember.cxx:259
 TDataMember.cxx:260
 TDataMember.cxx:261
 TDataMember.cxx:262
 TDataMember.cxx:263
 TDataMember.cxx:264
 TDataMember.cxx:265
 TDataMember.cxx:266
 TDataMember.cxx:267
 TDataMember.cxx:268
 TDataMember.cxx:269
 TDataMember.cxx:270
 TDataMember.cxx:271
 TDataMember.cxx:272
 TDataMember.cxx:273
 TDataMember.cxx:274
 TDataMember.cxx:275
 TDataMember.cxx:276
 TDataMember.cxx:277
 TDataMember.cxx:278
 TDataMember.cxx:279
 TDataMember.cxx:280
 TDataMember.cxx:281
 TDataMember.cxx:282
 TDataMember.cxx:283
 TDataMember.cxx:284
 TDataMember.cxx:285
 TDataMember.cxx:286
 TDataMember.cxx:287
 TDataMember.cxx:288
 TDataMember.cxx:289
 TDataMember.cxx:290
 TDataMember.cxx:291
 TDataMember.cxx:292
 TDataMember.cxx:293
 TDataMember.cxx:294
 TDataMember.cxx:295
 TDataMember.cxx:296
 TDataMember.cxx:297
 TDataMember.cxx:298
 TDataMember.cxx:299
 TDataMember.cxx:300
 TDataMember.cxx:301
 TDataMember.cxx:302
 TDataMember.cxx:303
 TDataMember.cxx:304
 TDataMember.cxx:305
 TDataMember.cxx:306
 TDataMember.cxx:307
 TDataMember.cxx:308
 TDataMember.cxx:309
 TDataMember.cxx:310
 TDataMember.cxx:311
 TDataMember.cxx:312
 TDataMember.cxx:313
 TDataMember.cxx:314
 TDataMember.cxx:315
 TDataMember.cxx:316
 TDataMember.cxx:317
 TDataMember.cxx:318
 TDataMember.cxx:319
 TDataMember.cxx:320
 TDataMember.cxx:321
 TDataMember.cxx:322
 TDataMember.cxx:323
 TDataMember.cxx:324
 TDataMember.cxx:325
 TDataMember.cxx:326
 TDataMember.cxx:327
 TDataMember.cxx:328
 TDataMember.cxx:329
 TDataMember.cxx:330
 TDataMember.cxx:331
 TDataMember.cxx:332
 TDataMember.cxx:333
 TDataMember.cxx:334
 TDataMember.cxx:335
 TDataMember.cxx:336
 TDataMember.cxx:337
 TDataMember.cxx:338
 TDataMember.cxx:339
 TDataMember.cxx:340
 TDataMember.cxx:341
 TDataMember.cxx:342
 TDataMember.cxx:343
 TDataMember.cxx:344
 TDataMember.cxx:345
 TDataMember.cxx:346
 TDataMember.cxx:347
 TDataMember.cxx:348
 TDataMember.cxx:349
 TDataMember.cxx:350
 TDataMember.cxx:351
 TDataMember.cxx:352
 TDataMember.cxx:353
 TDataMember.cxx:354
 TDataMember.cxx:355
 TDataMember.cxx:356
 TDataMember.cxx:357
 TDataMember.cxx:358
 TDataMember.cxx:359
 TDataMember.cxx:360
 TDataMember.cxx:361
 TDataMember.cxx:362
 TDataMember.cxx:363
 TDataMember.cxx:364
 TDataMember.cxx:365
 TDataMember.cxx:366
 TDataMember.cxx:367
 TDataMember.cxx:368
 TDataMember.cxx:369
 TDataMember.cxx:370
 TDataMember.cxx:371
 TDataMember.cxx:372
 TDataMember.cxx:373
 TDataMember.cxx:374
 TDataMember.cxx:375
 TDataMember.cxx:376
 TDataMember.cxx:377
 TDataMember.cxx:378
 TDataMember.cxx:379
 TDataMember.cxx:380
 TDataMember.cxx:381
 TDataMember.cxx:382
 TDataMember.cxx:383
 TDataMember.cxx:384
 TDataMember.cxx:385
 TDataMember.cxx:386
 TDataMember.cxx:387
 TDataMember.cxx:388
 TDataMember.cxx:389
 TDataMember.cxx:390
 TDataMember.cxx:391
 TDataMember.cxx:392
 TDataMember.cxx:393
 TDataMember.cxx:394
 TDataMember.cxx:395
 TDataMember.cxx:396
 TDataMember.cxx:397
 TDataMember.cxx:398
 TDataMember.cxx:399
 TDataMember.cxx:400
 TDataMember.cxx:401
 TDataMember.cxx:402
 TDataMember.cxx:403
 TDataMember.cxx:404
 TDataMember.cxx:405
 TDataMember.cxx:406
 TDataMember.cxx:407
 TDataMember.cxx:408
 TDataMember.cxx:409
 TDataMember.cxx:410
 TDataMember.cxx:411
 TDataMember.cxx:412
 TDataMember.cxx:413
 TDataMember.cxx:414
 TDataMember.cxx:415
 TDataMember.cxx:416
 TDataMember.cxx:417
 TDataMember.cxx:418
 TDataMember.cxx:419
 TDataMember.cxx:420
 TDataMember.cxx:421
 TDataMember.cxx:422
 TDataMember.cxx:423
 TDataMember.cxx:424
 TDataMember.cxx:425
 TDataMember.cxx:426
 TDataMember.cxx:427
 TDataMember.cxx:428
 TDataMember.cxx:429
 TDataMember.cxx:430
 TDataMember.cxx:431
 TDataMember.cxx:432
 TDataMember.cxx:433
 TDataMember.cxx:434
 TDataMember.cxx:435
 TDataMember.cxx:436
 TDataMember.cxx:437
 TDataMember.cxx:438
 TDataMember.cxx:439
 TDataMember.cxx:440
 TDataMember.cxx:441
 TDataMember.cxx:442
 TDataMember.cxx:443
 TDataMember.cxx:444
 TDataMember.cxx:445
 TDataMember.cxx:446
 TDataMember.cxx:447
 TDataMember.cxx:448
 TDataMember.cxx:449
 TDataMember.cxx:450
 TDataMember.cxx:451
 TDataMember.cxx:452
 TDataMember.cxx:453
 TDataMember.cxx:454
 TDataMember.cxx:455
 TDataMember.cxx:456
 TDataMember.cxx:457
 TDataMember.cxx:458
 TDataMember.cxx:459
 TDataMember.cxx:460
 TDataMember.cxx:461
 TDataMember.cxx:462
 TDataMember.cxx:463
 TDataMember.cxx:464
 TDataMember.cxx:465
 TDataMember.cxx:466
 TDataMember.cxx:467
 TDataMember.cxx:468
 TDataMember.cxx:469
 TDataMember.cxx:470
 TDataMember.cxx:471
 TDataMember.cxx:472
 TDataMember.cxx:473
 TDataMember.cxx:474
 TDataMember.cxx:475
 TDataMember.cxx:476
 TDataMember.cxx:477
 TDataMember.cxx:478
 TDataMember.cxx:479
 TDataMember.cxx:480
 TDataMember.cxx:481
 TDataMember.cxx:482
 TDataMember.cxx:483
 TDataMember.cxx:484
 TDataMember.cxx:485
 TDataMember.cxx:486
 TDataMember.cxx:487
 TDataMember.cxx:488
 TDataMember.cxx:489
 TDataMember.cxx:490
 TDataMember.cxx:491
 TDataMember.cxx:492
 TDataMember.cxx:493
 TDataMember.cxx:494
 TDataMember.cxx:495
 TDataMember.cxx:496
 TDataMember.cxx:497
 TDataMember.cxx:498
 TDataMember.cxx:499
 TDataMember.cxx:500
 TDataMember.cxx:501
 TDataMember.cxx:502
 TDataMember.cxx:503
 TDataMember.cxx:504
 TDataMember.cxx:505
 TDataMember.cxx:506
 TDataMember.cxx:507
 TDataMember.cxx:508
 TDataMember.cxx:509
 TDataMember.cxx:510
 TDataMember.cxx:511
 TDataMember.cxx:512
 TDataMember.cxx:513
 TDataMember.cxx:514
 TDataMember.cxx:515
 TDataMember.cxx:516
 TDataMember.cxx:517
 TDataMember.cxx:518
 TDataMember.cxx:519
 TDataMember.cxx:520
 TDataMember.cxx:521
 TDataMember.cxx:522
 TDataMember.cxx:523
 TDataMember.cxx:524
 TDataMember.cxx:525
 TDataMember.cxx:526
 TDataMember.cxx:527
 TDataMember.cxx:528
 TDataMember.cxx:529
 TDataMember.cxx:530
 TDataMember.cxx:531
 TDataMember.cxx:532
 TDataMember.cxx:533
 TDataMember.cxx:534
 TDataMember.cxx:535
 TDataMember.cxx:536
 TDataMember.cxx:537
 TDataMember.cxx:538
 TDataMember.cxx:539
 TDataMember.cxx:540
 TDataMember.cxx:541
 TDataMember.cxx:542
 TDataMember.cxx:543
 TDataMember.cxx:544
 TDataMember.cxx:545
 TDataMember.cxx:546
 TDataMember.cxx:547
 TDataMember.cxx:548
 TDataMember.cxx:549
 TDataMember.cxx:550
 TDataMember.cxx:551
 TDataMember.cxx:552
 TDataMember.cxx:553
 TDataMember.cxx:554
 TDataMember.cxx:555
 TDataMember.cxx:556
 TDataMember.cxx:557
 TDataMember.cxx:558
 TDataMember.cxx:559
 TDataMember.cxx:560
 TDataMember.cxx:561
 TDataMember.cxx:562
 TDataMember.cxx:563
 TDataMember.cxx:564
 TDataMember.cxx:565
 TDataMember.cxx:566
 TDataMember.cxx:567
 TDataMember.cxx:568
 TDataMember.cxx:569
 TDataMember.cxx:570
 TDataMember.cxx:571
 TDataMember.cxx:572
 TDataMember.cxx:573
 TDataMember.cxx:574
 TDataMember.cxx:575
 TDataMember.cxx:576
 TDataMember.cxx:577
 TDataMember.cxx:578
 TDataMember.cxx:579
 TDataMember.cxx:580
 TDataMember.cxx:581
 TDataMember.cxx:582
 TDataMember.cxx:583
 TDataMember.cxx:584
 TDataMember.cxx:585
 TDataMember.cxx:586
 TDataMember.cxx:587
 TDataMember.cxx:588
 TDataMember.cxx:589
 TDataMember.cxx:590
 TDataMember.cxx:591
 TDataMember.cxx:592
 TDataMember.cxx:593
 TDataMember.cxx:594
 TDataMember.cxx:595
 TDataMember.cxx:596
 TDataMember.cxx:597
 TDataMember.cxx:598
 TDataMember.cxx:599
 TDataMember.cxx:600
 TDataMember.cxx:601
 TDataMember.cxx:602
 TDataMember.cxx:603
 TDataMember.cxx:604
 TDataMember.cxx:605
 TDataMember.cxx:606
 TDataMember.cxx:607
 TDataMember.cxx:608
 TDataMember.cxx:609
 TDataMember.cxx:610
 TDataMember.cxx:611
 TDataMember.cxx:612
 TDataMember.cxx:613
 TDataMember.cxx:614
 TDataMember.cxx:615
 TDataMember.cxx:616
 TDataMember.cxx:617
 TDataMember.cxx:618
 TDataMember.cxx:619
 TDataMember.cxx:620
 TDataMember.cxx:621
 TDataMember.cxx:622
 TDataMember.cxx:623
 TDataMember.cxx:624
 TDataMember.cxx:625
 TDataMember.cxx:626
 TDataMember.cxx:627
 TDataMember.cxx:628
 TDataMember.cxx:629
 TDataMember.cxx:630
 TDataMember.cxx:631
 TDataMember.cxx:632
 TDataMember.cxx:633
 TDataMember.cxx:634
 TDataMember.cxx:635
 TDataMember.cxx:636
 TDataMember.cxx:637
 TDataMember.cxx:638
 TDataMember.cxx:639
 TDataMember.cxx:640
 TDataMember.cxx:641
 TDataMember.cxx:642
 TDataMember.cxx:643
 TDataMember.cxx:644
 TDataMember.cxx:645
 TDataMember.cxx:646
 TDataMember.cxx:647
 TDataMember.cxx:648
 TDataMember.cxx:649
 TDataMember.cxx:650
 TDataMember.cxx:651
 TDataMember.cxx:652
 TDataMember.cxx:653
 TDataMember.cxx:654
 TDataMember.cxx:655
 TDataMember.cxx:656
 TDataMember.cxx:657
 TDataMember.cxx:658
 TDataMember.cxx:659
 TDataMember.cxx:660
 TDataMember.cxx:661
 TDataMember.cxx:662
 TDataMember.cxx:663
 TDataMember.cxx:664
 TDataMember.cxx:665
 TDataMember.cxx:666
 TDataMember.cxx:667
 TDataMember.cxx:668
 TDataMember.cxx:669
 TDataMember.cxx:670
 TDataMember.cxx:671
 TDataMember.cxx:672
 TDataMember.cxx:673
 TDataMember.cxx:674
 TDataMember.cxx:675
 TDataMember.cxx:676
 TDataMember.cxx:677
 TDataMember.cxx:678
 TDataMember.cxx:679
 TDataMember.cxx:680
 TDataMember.cxx:681
 TDataMember.cxx:682
 TDataMember.cxx:683
 TDataMember.cxx:684
 TDataMember.cxx:685
 TDataMember.cxx:686
 TDataMember.cxx:687
 TDataMember.cxx:688
 TDataMember.cxx:689
 TDataMember.cxx:690
 TDataMember.cxx:691
 TDataMember.cxx:692
 TDataMember.cxx:693
 TDataMember.cxx:694
 TDataMember.cxx:695
 TDataMember.cxx:696
 TDataMember.cxx:697
 TDataMember.cxx:698
 TDataMember.cxx:699
 TDataMember.cxx:700
 TDataMember.cxx:701
 TDataMember.cxx:702
 TDataMember.cxx:703
 TDataMember.cxx:704
 TDataMember.cxx:705
 TDataMember.cxx:706
 TDataMember.cxx:707
 TDataMember.cxx:708
 TDataMember.cxx:709
 TDataMember.cxx:710
 TDataMember.cxx:711
 TDataMember.cxx:712
 TDataMember.cxx:713
 TDataMember.cxx:714
 TDataMember.cxx:715
 TDataMember.cxx:716
 TDataMember.cxx:717
 TDataMember.cxx:718
 TDataMember.cxx:719
 TDataMember.cxx:720
 TDataMember.cxx:721
 TDataMember.cxx:722
 TDataMember.cxx:723
 TDataMember.cxx:724
 TDataMember.cxx:725
 TDataMember.cxx:726
 TDataMember.cxx:727
 TDataMember.cxx:728
 TDataMember.cxx:729
 TDataMember.cxx:730
 TDataMember.cxx:731
 TDataMember.cxx:732
 TDataMember.cxx:733
 TDataMember.cxx:734
 TDataMember.cxx:735
 TDataMember.cxx:736
 TDataMember.cxx:737
 TDataMember.cxx:738
 TDataMember.cxx:739
 TDataMember.cxx:740
 TDataMember.cxx:741
 TDataMember.cxx:742
 TDataMember.cxx:743
 TDataMember.cxx:744
 TDataMember.cxx:745
 TDataMember.cxx:746
 TDataMember.cxx:747
 TDataMember.cxx:748
 TDataMember.cxx:749
 TDataMember.cxx:750
 TDataMember.cxx:751
 TDataMember.cxx:752
 TDataMember.cxx:753
 TDataMember.cxx:754
 TDataMember.cxx:755
 TDataMember.cxx:756
 TDataMember.cxx:757
 TDataMember.cxx:758
 TDataMember.cxx:759
 TDataMember.cxx:760
 TDataMember.cxx:761
 TDataMember.cxx:762
 TDataMember.cxx:763
 TDataMember.cxx:764
 TDataMember.cxx:765
 TDataMember.cxx:766
 TDataMember.cxx:767
 TDataMember.cxx:768
 TDataMember.cxx:769
 TDataMember.cxx:770
 TDataMember.cxx:771
 TDataMember.cxx:772
 TDataMember.cxx:773
 TDataMember.cxx:774
 TDataMember.cxx:775
 TDataMember.cxx:776
 TDataMember.cxx:777
 TDataMember.cxx:778
 TDataMember.cxx:779
 TDataMember.cxx:780
 TDataMember.cxx:781
 TDataMember.cxx:782
 TDataMember.cxx:783
 TDataMember.cxx:784
 TDataMember.cxx:785
 TDataMember.cxx:786
 TDataMember.cxx:787
 TDataMember.cxx:788
 TDataMember.cxx:789
 TDataMember.cxx:790
 TDataMember.cxx:791
 TDataMember.cxx:792
 TDataMember.cxx:793
 TDataMember.cxx:794
 TDataMember.cxx:795
 TDataMember.cxx:796
 TDataMember.cxx:797
 TDataMember.cxx:798
 TDataMember.cxx:799
 TDataMember.cxx:800
 TDataMember.cxx:801
 TDataMember.cxx:802
 TDataMember.cxx:803
 TDataMember.cxx:804
 TDataMember.cxx:805
 TDataMember.cxx:806
 TDataMember.cxx:807
 TDataMember.cxx:808
 TDataMember.cxx:809
 TDataMember.cxx:810
 TDataMember.cxx:811
 TDataMember.cxx:812
 TDataMember.cxx:813
 TDataMember.cxx:814
 TDataMember.cxx:815
 TDataMember.cxx:816
 TDataMember.cxx:817
 TDataMember.cxx:818
 TDataMember.cxx:819
 TDataMember.cxx:820
 TDataMember.cxx:821
 TDataMember.cxx:822
 TDataMember.cxx:823
 TDataMember.cxx:824
 TDataMember.cxx:825
 TDataMember.cxx:826
 TDataMember.cxx:827
 TDataMember.cxx:828
 TDataMember.cxx:829
 TDataMember.cxx:830
 TDataMember.cxx:831
 TDataMember.cxx:832
 TDataMember.cxx:833
 TDataMember.cxx:834
 TDataMember.cxx:835
 TDataMember.cxx:836
 TDataMember.cxx:837
 TDataMember.cxx:838
 TDataMember.cxx:839
 TDataMember.cxx:840
 TDataMember.cxx:841
 TDataMember.cxx:842
 TDataMember.cxx:843
 TDataMember.cxx:844
 TDataMember.cxx:845
 TDataMember.cxx:846
 TDataMember.cxx:847
 TDataMember.cxx:848
 TDataMember.cxx:849
 TDataMember.cxx:850
 TDataMember.cxx:851
 TDataMember.cxx:852
 TDataMember.cxx:853
 TDataMember.cxx:854
 TDataMember.cxx:855
 TDataMember.cxx:856
 TDataMember.cxx:857
 TDataMember.cxx:858
 TDataMember.cxx:859
 TDataMember.cxx:860
 TDataMember.cxx:861
 TDataMember.cxx:862
 TDataMember.cxx:863
 TDataMember.cxx:864
 TDataMember.cxx:865
 TDataMember.cxx:866
 TDataMember.cxx:867
 TDataMember.cxx:868
 TDataMember.cxx:869
 TDataMember.cxx:870
 TDataMember.cxx:871
 TDataMember.cxx:872
 TDataMember.cxx:873
 TDataMember.cxx:874
 TDataMember.cxx:875
 TDataMember.cxx:876
 TDataMember.cxx:877
 TDataMember.cxx:878
 TDataMember.cxx:879
 TDataMember.cxx:880
 TDataMember.cxx:881
 TDataMember.cxx:882
 TDataMember.cxx:883
 TDataMember.cxx:884
 TDataMember.cxx:885
 TDataMember.cxx:886
 TDataMember.cxx:887
 TDataMember.cxx:888
 TDataMember.cxx:889
 TDataMember.cxx:890
 TDataMember.cxx:891
 TDataMember.cxx:892
 TDataMember.cxx:893
 TDataMember.cxx:894
 TDataMember.cxx:895
 TDataMember.cxx:896
 TDataMember.cxx:897
 TDataMember.cxx:898
 TDataMember.cxx:899
 TDataMember.cxx:900
 TDataMember.cxx:901
 TDataMember.cxx:902
 TDataMember.cxx:903
 TDataMember.cxx:904
 TDataMember.cxx:905
 TDataMember.cxx:906
 TDataMember.cxx:907
 TDataMember.cxx:908
 TDataMember.cxx:909
 TDataMember.cxx:910
 TDataMember.cxx:911
 TDataMember.cxx:912
 TDataMember.cxx:913
 TDataMember.cxx:914
 TDataMember.cxx:915
 TDataMember.cxx:916
 TDataMember.cxx:917
 TDataMember.cxx:918
 TDataMember.cxx:919
 TDataMember.cxx:920
 TDataMember.cxx:921
 TDataMember.cxx:922
 TDataMember.cxx:923
 TDataMember.cxx:924
 TDataMember.cxx:925
 TDataMember.cxx:926
 TDataMember.cxx:927
 TDataMember.cxx:928
 TDataMember.cxx:929
 TDataMember.cxx:930
 TDataMember.cxx:931
 TDataMember.cxx:932
 TDataMember.cxx:933
 TDataMember.cxx:934
 TDataMember.cxx:935
 TDataMember.cxx:936
 TDataMember.cxx:937
 TDataMember.cxx:938
 TDataMember.cxx:939
 TDataMember.cxx:940
 TDataMember.cxx:941
 TDataMember.cxx:942
 TDataMember.cxx:943
 TDataMember.cxx:944
 TDataMember.cxx:945
 TDataMember.cxx:946
 TDataMember.cxx:947
 TDataMember.cxx:948
 TDataMember.cxx:949
 TDataMember.cxx:950
 TDataMember.cxx:951
 TDataMember.cxx:952
 TDataMember.cxx:953
 TDataMember.cxx:954
 TDataMember.cxx:955
 TDataMember.cxx:956
 TDataMember.cxx:957
 TDataMember.cxx:958
 TDataMember.cxx:959
 TDataMember.cxx:960
 TDataMember.cxx:961
 TDataMember.cxx:962
 TDataMember.cxx:963
 TDataMember.cxx:964
 TDataMember.cxx:965
 TDataMember.cxx:966
 TDataMember.cxx:967
 TDataMember.cxx:968
 TDataMember.cxx:969
 TDataMember.cxx:970
 TDataMember.cxx:971
 TDataMember.cxx:972
 TDataMember.cxx:973
 TDataMember.cxx:974
 TDataMember.cxx:975
 TDataMember.cxx:976
 TDataMember.cxx:977
 TDataMember.cxx:978
 TDataMember.cxx:979
 TDataMember.cxx:980
 TDataMember.cxx:981
 TDataMember.cxx:982
 TDataMember.cxx:983
 TDataMember.cxx:984
 TDataMember.cxx:985
 TDataMember.cxx:986
 TDataMember.cxx:987