// @(#)root/meta:$Id$
// Author: Rene Brun   07/01/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.             *
 *************************************************************************/

#ifndef ROOT_TClass
#define ROOT_TClass


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClass                                                               //
//                                                                      //
// Dictionary of a class.                                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TDictionary
#include "TDictionary.h"
#endif
#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TObjArray
#include "TObjArray.h"
#endif
#ifndef ROOT_TObjString
#include "TObjString.h"
#endif

#include <map>
#include <string>
#include <set>
#include <unordered_set>
#include <vector>

#include <atomic>
#ifndef ROOT_ThreadLocalStorage
#include "ThreadLocalStorage.h"
#endif
class TBaseClass;
class TBrowser;
class TDataMember;
class TCling;
class TMethod;
class TRealData;
class TBuffer;
class TVirtualStreamerInfo;
class TVirtualCollectionProxy;
class TMethodCall;
class TVirtualIsAProxy;
class TVirtualRefProxy;
class THashTable;
class TListOfFunctions;
class TListOfFunctionTemplates;
class TListOfDataMembers;
class TListOfEnums;
class TViewPubFunctions;
class TViewPubDataMembers;
class TFunctionTemplate;
class TProtoClass;

namespace clang {
   class Decl;
}

namespace ROOT {
   class TGenericClassInfo;
   class TCollectionProxyInfo;
   class TSchemaRuleSet;
}

namespace ROOT {
   class TMapTypeToTClass;
   class TMapDeclIdToTClass;
}
typedef ROOT::TMapTypeToTClass IdMap_t;
typedef ROOT::TMapDeclIdToTClass DeclIdMap_t;

class TClass : public TDictionary {

friend class TCling;
friend void ROOT::ResetClassVersion(TClass*, const char*, Short_t);
friend class ROOT::TGenericClassInfo;
friend class TProtoClass;

public:
   // TClass status bits
   enum { kClassSaved  = BIT(12), kIgnoreTObjectStreamer = BIT(15),
          kUnloaded    = BIT(16), // The library containing the dictionary for this class was
                                  // loaded and has been unloaded from memory.
          kIsTObject = BIT(17),
          kIsForeign   = BIT(18),
          kIsEmulation = BIT(19), // Deprecated
          kStartWithTObject = BIT(20),  // see comments for IsStartingWithTObject()
          kWarned      = BIT(21),
          kHasNameMapNode = BIT(22),
          kHasCustomStreamerMember = BIT(23) // The class has a Streamer method and it is implemented by the user or an older (not StreamerInfo based) automatic streamer.
   };
   enum ENewType { kRealNew = 0, kClassNew, kDummyNew };
   enum ECheckSum {
      kCurrentCheckSum = 0,
      kNoEnum          = 1, // Used since v3.3
      kReflexNoComment = 2, // Up to v5.34.18 (has no range/comment and no typedef at all)
      kNoRange         = 3, // Up to v5.17
      kWithTypeDef     = 4, // Up to v5.34.18 and v5.99/06
      kReflex          = 5, // Up to v5.34.18 (has no typedef at all)
      kNoRangeCheck    = 6, // Up to v5.34.18 and v5.99/06
      kNoBaseCheckSum  = 7, // Up to v5.34.18 and v5.99/06
      kLatestCheckSum  = 8
   };

   // Describe the current state of the TClass itself.
   enum EState {
      kNoInfo,          // The state has not yet been initialized, i.e. the TClass
                        // was just created and/or there is no trace of it in the interpreter.
      kForwardDeclared, // The interpreted knows the entity is a class but that's it.
      kEmulated,        // The information about the class only comes from a TStreamerInfo
      kInterpreted,     // The class is described completely/only in the interpreter database.
      kHasTClassInit,   // The class has a TClass proper bootstrap coming from a run
                        // through rootcling/genreflex/TMetaUtils and the library
                        // containing this dictionary has been loaded in memory.
      kLoaded = kHasTClassInit,
      kNamespaceForMeta // Very transient state necessary to bootstrap namespace entries in ROOT Meta w/o interpreter information
   };

private:

   class TSpinLockGuard {
      // Trivial spin lock guard
   public:
      TSpinLockGuard(std::atomic_flag& aflag);
      ~TSpinLockGuard();
   private:
      std::atomic_flag& fAFlag;
   };

   class TDeclNameRegistry {
      // A class which is used to collect decl names starting from normalised
      // names (typedef resolution is excluded here, just string manipulation
      // is performed). At the heart of the implementation, an unordered set.
   public:
      TDeclNameRegistry(Int_t verbLevel=0);
      void AddQualifiedName(const char *name);
      Bool_t HasDeclName(const char *name) const;
      ~TDeclNameRegistry();
   private:
      Int_t fVerbLevel=0;
      std::unordered_set<std::string> fClassNamesSet;
      mutable std::atomic_flag fSpinLock; // MSVC doesn't support = ATOMIC_FLAG_INIT;
   };

   class InsertTClassInRegistryRAII {
      // Trivial RAII used to insert names in the registry
      TClass::EState& fState;
      const char* fName;
      TDeclNameRegistry& fNoInfoOrEmuOrFwdDeclNameRegistry;
   public:
      InsertTClassInRegistryRAII(TClass::EState &state, const char *name, TDeclNameRegistry &emuRegistry);
      ~InsertTClassInRegistryRAII();
   };

   // TClass objects can be created as a result of opening a TFile (in which
   // they are in emulated mode) or as a result of loading the dictionary for
   // the corresponding class.   When a dictionary is loaded any pre-existing
   // emulated TClass is replaced by the one created/coming from the dictionary.
   // To have a reference that always point to the 'current' TClass object for
   // a given class, one should use a TClassRef.
   // TClassRef works by holding on to the fPersistentRef which is updated
   // atomically whenever a TClass is replaced.  During the replacement the
   // value of fPersistentRef is set to zero, leading the TClassRef to call
   // TClass::GetClass which is also locked by the replacement.   At the end
   // of the replacement, fPersistentRef points to the new TClass object.
   std::atomic<TClass**> fPersistentRef;//!Persistent address of pointer to this TClass object and its successors.

   typedef std::atomic<std::map<std::string, TObjArray*>*> ConvSIMap_t;

   mutable TObjArray  *fStreamerInfo;           //Array of TVirtualStreamerInfo
   mutable ConvSIMap_t fConversionStreamerInfo; //Array of the streamer infos derived from another class.
   TList              *fRealData;        //linked list for persistent members including base classes
   TList              *fBase;            //linked list for base classes
   TListOfDataMembers *fData;            //linked list for data members

   std::atomic<TListOfEnums*> fEnums;        //linked list for the enums
   TListOfFunctionTemplates  *fFuncTemplate; //linked list for function templates [Not public until implemented as active list]
   std::atomic<TListOfFunctions*> fMethod;   //linked list for methods

   TViewPubDataMembers*fAllPubData;     //all public data members (including from base classes)
   TViewPubFunctions *fAllPubMethod;    //all public methods (including from base classes)
   mutable TList     *fClassMenuList;   //list of class menu items

   const char        *fDeclFileName;    //name of class declaration file
   const char        *fImplFileName;    //name of class implementation file
   Short_t            fDeclFileLine;    //line of class declaration
   Short_t            fImplFileLine;    //line of class implementation
   UInt_t             fInstanceCount;   //number of instances of this class
   UInt_t             fOnHeap;          //number of instances on heap
   mutable UInt_t     fCheckSum;        //checksum of data members and base classes
   TVirtualCollectionProxy *fCollectionProxy; //Collection interface
   Version_t          fClassVersion;    //Class version Identifier
   ClassInfo_t       *fClassInfo;       //pointer to CINT class info class
   TString            fContextMenuTitle;//context menu title
   const type_info   *fTypeInfo;        //pointer to the C++ type information.
   ShowMembersFunc_t  fShowMembers;     //pointer to the class's ShowMembers function
   TClassStreamer    *fStreamer;        //pointer to streamer function
   TString            fSharedLibs;      //shared libraries containing class code

   TVirtualIsAProxy  *fIsA;             //!pointer to the class's IsA proxy.
   IsAGlobalFunc_t    fGlobalIsA;       //pointer to a global IsA function.
   mutable std::atomic<TMethodCall*> fIsAMethod;       //!saved info to call a IsA member function

   ROOT::MergeFunc_t   fMerge;          //pointer to a function implementing Merging objects of this class.
   ROOT::ResetAfterMergeFunc_t fResetAfterMerge; //pointer to a function implementing Merging objects of this class.
   ROOT::NewFunc_t     fNew;            //pointer to a function newing one object.
   ROOT::NewArrFunc_t  fNewArray;       //pointer to a function newing an array of objects.
   ROOT::DelFunc_t     fDelete;         //pointer to a function deleting one object.
   ROOT::DelArrFunc_t  fDeleteArray;    //pointer to a function deleting an array of objects.
   ROOT::DesFunc_t     fDestructor;     //pointer to a function call an object's destructor.
   ROOT::DirAutoAdd_t  fDirAutoAdd;     //pointer which implements the Directory Auto Add feature for this class.']'
   ClassStreamerFunc_t fStreamerFunc;   //Wrapper around this class custom Streamer member function.
   ClassConvStreamerFunc_t fConvStreamerFunc;   //Wrapper around this class custom conversion Streamer member function.
   Int_t               fSizeof;         //Sizeof the class.

           Int_t      fCanSplit;          //!Indicates whether this class can be split or not.
   mutable std::atomic<Long_t> fProperty; //!Property
   mutable Long_t     fClassProperty;     //!C++ Property of the class (is abstract, has virtual table, etc.)

           // fHasRootPcmInfo needs to be atomic as long as GetListOfBases needs to modify it.
           std::atomic<Bool_t> fHasRootPcmInfo;      //!Whether info was loaded from a root pcm.
   mutable std::atomic<Bool_t> fCanLoadClassInfo;    //!Indicates whether the ClassInfo is supposed to be available.
   mutable std::atomic<Bool_t> fIsOffsetStreamerSet; //!saved remember if fOffsetStreamer has been set.
   mutable std::atomic<Bool_t> fVersionUsed;         //!Indicates whether GetClassVersion has been called

   mutable Long_t     fOffsetStreamer;  //!saved info to call Streamer
   Int_t              fStreamerType;    //!cached of the streaming method to use
   EState             fState;           //!Current 'state' of the class (Emulated,Interpreted,Loaded)
   mutable std::atomic<TVirtualStreamerInfo*>  fCurrentInfo;     //!cached current streamer info.
   mutable std::atomic<TVirtualStreamerInfo*>  fLastReadInfo;    //!cached streamer info used in the last read.
   TVirtualRefProxy  *fRefProxy;        //!Pointer to reference proxy if this class represents a reference
   ROOT::TSchemaRuleSet *fSchemaRules;  //! Schema evolution rules

   typedef void (*StreamerImpl_t)(const TClass* pThis, void *obj, TBuffer &b, const TClass *onfile_class);
#ifdef R__NO_ATOMIC_FUNCTION_POINTER
   mutable StreamerImpl_t fStreamerImpl;  //! Pointer to the function implementing the right streaming behavior for the class represented by this object.
#else
   mutable std::atomic<StreamerImpl_t> fStreamerImpl;  //! Pointer to the function implementing the right streaming behavior for the class represented by this object.
#endif

   TListOfFunctions  *GetMethodList();
   TMethod           *GetClassMethod(Long_t faddr);
   TMethod           *FindClassOrBaseMethodWithId(DeclId_t faddr);
   Int_t              GetBaseClassOffsetRecurse(const TClass *toBase);
   void Init(const char *name, Version_t cversion, const type_info *info,
             TVirtualIsAProxy *isa,
             const char *dfil, const char *ifil,
             Int_t dl, Int_t il,
             ClassInfo_t *classInfo,
             Bool_t silent);
   void ForceReload (TClass* oldcl);
   void LoadClassInfo() const;

   static TClass     *LoadClassDefault(const char *requestedname, Bool_t silent);
   static TClass     *LoadClassCustom(const char *requestedname, Bool_t silent);

   void               SetClassVersion(Version_t version);
   void               SetClassSize(Int_t sizof) { fSizeof = sizof; }
   TVirtualStreamerInfo* DetermineCurrentStreamerInfo();

   void SetStreamerImpl();

   // Various implementation for TClass::Stramer
   static void StreamerExternal(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void StreamerTObject(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void StreamerTObjectInitialized(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void StreamerTObjectEmulated(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void StreamerInstrumented(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void ConvStreamerInstrumented(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void StreamerStreamerInfo(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
   static void StreamerDefault(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);

   static IdMap_t    *GetIdMap();       //Map from typeid to TClass pointer
   static DeclIdMap_t *GetDeclIdMap();  //Map from DeclId_t to TClass pointer
   static std::atomic<Int_t>     fgClassCount;  //provides unique id for a each class
                                                //stored in TObject::fUniqueID
   static TDeclNameRegistry fNoInfoOrEmuOrFwdDeclNameRegistry; // Store the decl names of the forwardd and no info instances
   static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char*);

   // Internal status bits, set and reset only during initialization and thus under the protection of the global lock.
   enum { kLoading = BIT(14), kUnloading = BIT(14) };
   // Internal streamer type.
   enum EStreamerType {kDefault=0, kEmulatedStreamer=1, kTObject=2, kInstrumented=4, kForeign=8, kExternal=16};

   // When a new class is created, we need to be able to find
   // if there are any existing classes that have the same name
   // after any typedefs are expanded.  (This only really affects
   // template arguments.)  To avoid having to search through all classes
   // in that case, we keep a hash table mapping from the fully
   // typedef-expanded names to the original class names.
   // An entry is made in the table only if they are actually different.
   //
   // In these objects, the TObjString base holds the typedef-expanded
   // name (the hash key), and fOrigName holds the original class name
   // (the value to which the key maps).
   //
   class TNameMapNode : public TObjString
   {
   public:
      TNameMapNode (const char* typedf, const char* orig);
      TString fOrigName;
   };

   // These are the above-referenced hash tables.  (The pointers are null
   // if no entries have been made.)
   static THashTable* fgClassTypedefHash;

private:
   TClass(const TClass& tc) = delete;
   TClass& operator=(const TClass&) = delete;

protected:
   TVirtualStreamerInfo     *FindStreamerInfo(TObjArray* arr, UInt_t checksum) const;
   void                      GetMissingDictionariesForBaseClasses(TCollection& result, TCollection& visited, bool recurse);
   void                      GetMissingDictionariesForMembers(TCollection& result, TCollection& visited, bool recurse);
   void                      GetMissingDictionariesWithRecursionCheck(TCollection& result, TCollection& visited, bool recurse);
   void                      GetMissingDictionariesForPairElements(TCollection& result, TCollection& visited, bool recurse);

public:
   TClass();
   TClass(const char *name, Bool_t silent = kFALSE);
   TClass(const char *name, Version_t cversion, Bool_t silent = kFALSE);
   TClass(const char *name, Version_t cversion, EState theState, Bool_t silent = kFALSE);
   TClass(ClassInfo_t *info, Version_t cversion,
          const char *dfil, const char *ifil = 0,
          Int_t dl = 0, Int_t il = 0, Bool_t silent = kFALSE);
   TClass(const char *name, Version_t cversion,
          const char *dfil, const char *ifil = 0,
          Int_t dl = 0, Int_t il = 0, Bool_t silent = kFALSE);
   TClass(const char *name, Version_t cversion,
          const type_info &info, TVirtualIsAProxy *isa,
          const char *dfil, const char *ifil,
          Int_t dl, Int_t il, Bool_t silent = kFALSE);
   virtual           ~TClass();

   void               AddInstance(Bool_t heap = kFALSE) { fInstanceCount++; if (heap) fOnHeap++; }
   void               AddImplFile(const char *filename, int line);
   static Bool_t      AddRule(const char *rule);
   static Int_t       ReadRules(const char *filename);
   static Int_t       ReadRules();
   void               AdoptSchemaRules( ROOT::TSchemaRuleSet *rules );
   virtual void       Browse(TBrowser *b);
   void               BuildRealData(void *pointer=0, Bool_t isTransient = kFALSE);
   void               BuildEmulatedRealData(const char *name, Long_t offset, TClass *cl);
   void               CalculateStreamerOffset() const;
   Bool_t             CallShowMembers(const void* obj, TMemberInspector &insp, Bool_t isTransient = kFALSE) const;
   Bool_t             CanSplit() const;
   Bool_t             CanIgnoreTObjectStreamer() { return TestBit(kIgnoreTObjectStreamer);}
   Long_t             ClassProperty() const;
   TObject           *Clone(const char *newname="") const;
   void               CopyCollectionProxy(const TVirtualCollectionProxy&);
   void               Draw(Option_t *option="");
   void               Dump() const { TDictionary::Dump(); }
   void               Dump(const void *obj, Bool_t noAddr = kFALSE) const;
   char              *EscapeChars(const char *text) const;
   TVirtualStreamerInfo     *FindStreamerInfo(UInt_t checksum) const;
   TVirtualStreamerInfo     *GetConversionStreamerInfo( const char* onfile_classname, Int_t version ) const;
   TVirtualStreamerInfo     *FindConversionStreamerInfo( const char* onfile_classname, UInt_t checksum ) const;
   TVirtualStreamerInfo     *GetConversionStreamerInfo( const TClass* onfile_cl, Int_t version ) const;
   TVirtualStreamerInfo     *FindConversionStreamerInfo( const TClass* onfile_cl, UInt_t checksum ) const;
   Bool_t             HasDataMemberInfo() const { return fHasRootPcmInfo || HasInterpreterInfo(); }
   Bool_t             HasDefaultConstructor() const;
   Bool_t             HasInterpreterInfoInMemory() const { return 0 != fClassInfo; }
   Bool_t             HasInterpreterInfo() const { return fCanLoadClassInfo || fClassInfo; }
   UInt_t             GetCheckSum(ECheckSum code = kCurrentCheckSum) const;
   UInt_t             GetCheckSum(Bool_t &isvalid) const;
   UInt_t             GetCheckSum(ECheckSum code, Bool_t &isvalid) const;
   TVirtualCollectionProxy *GetCollectionProxy() const;
   TVirtualIsAProxy  *GetIsAProxy() const;
   TMethod           *GetClassMethod(const char *name, const char *params, Bool_t objectIsConst = kFALSE);
   TMethod           *GetClassMethodWithPrototype(const char *name, const char *proto, Bool_t objectIsConst = kFALSE, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch);
   Version_t          GetClassVersion() const { fVersionUsed = kTRUE; return fClassVersion; }
   Int_t              GetClassSize() const { return Size(); }
   TDataMember       *GetDataMember(const char *datamember) const;
   Long_t             GetDataMemberOffset(const char *membername) const;
   const char        *GetDeclFileName() const { return fDeclFileName; }
   Short_t            GetDeclFileLine() const { return fDeclFileLine; }
   ROOT::DelFunc_t    GetDelete() const;
   ROOT::DesFunc_t    GetDestructor() const;
   ROOT::DelArrFunc_t GetDeleteArray() const;
   ClassInfo_t       *GetClassInfo() const { if (fCanLoadClassInfo && !TestBit(kLoading)) LoadClassInfo(); return fClassInfo; }
   const char        *GetContextMenuTitle() const { return fContextMenuTitle; }
   TVirtualStreamerInfo     *GetCurrentStreamerInfo() {
      if (fCurrentInfo.load()) return fCurrentInfo;
      else return DetermineCurrentStreamerInfo();
   }
   TVirtualStreamerInfo     *GetLastReadInfo() const { return fLastReadInfo; }
   void                      SetLastReadInfo(TVirtualStreamerInfo *info) { fLastReadInfo = info; }
   TList             *GetListOfDataMembers(Bool_t load = kTRUE);
   TList             *GetListOfEnums(Bool_t load = kTRUE);
   TList             *GetListOfFunctionTemplates(Bool_t load = kTRUE);
   TList             *GetListOfBases();
   TList             *GetListOfMethods(Bool_t load = kTRUE);
   TCollection       *GetListOfMethodOverloads(const char* name) const;
   TList             *GetListOfRealData() const { return fRealData; }
   const TList       *GetListOfAllPublicMethods(Bool_t load = kTRUE);
   TList             *GetListOfAllPublicDataMembers(Bool_t load = kTRUE);
   const char        *GetImplFileName() const { return fImplFileName; }
   Short_t            GetImplFileLine() const { return fImplFileLine; }
   TClass            *GetActualClass(const void *object) const;
   TClass            *GetBaseClass(const char *classname);
   TClass            *GetBaseClass(const TClass *base);
   Int_t              GetBaseClassOffset(const TClass *toBase, void *address = 0, bool isDerivedObject = true);
   TClass            *GetBaseDataMember(const char *datamember);
   ROOT::ESTLType     GetCollectionType() const;
   ROOT::DirAutoAdd_t GetDirectoryAutoAdd() const;
   TFunctionTemplate *GetFunctionTemplate(const char *name);
   UInt_t             GetInstanceCount() const { return fInstanceCount; }
   UInt_t             GetHeapInstanceCount() const { return fOnHeap; }
   void               GetMenuItems(TList *listitems);
   TList             *GetMenuList() const;
   TMethod           *GetMethod(const char *method, const char *params, Bool_t objectIsConst = kFALSE);
   TMethod           *GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst = kFALSE, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch);
   TMethod           *GetMethodAny(const char *method);
   TMethod           *GetMethodAllAny(const char *method);
   Int_t              GetNdata();
   ROOT::MergeFunc_t  GetMerge() const;
   ROOT::ResetAfterMergeFunc_t  GetResetAfterMerge() const;
   ROOT::NewFunc_t    GetNew() const;
   ROOT::NewArrFunc_t GetNewArray() const;
   Int_t              GetNmethods();
#ifdef __CINT__
   TClass           **GetPersistentRef() const { return fPersistentRef; }
#else
   TClass      *const*GetPersistentRef() const { return fPersistentRef; }
#endif
   TRealData         *GetRealData(const char *name) const;
   TVirtualRefProxy  *GetReferenceProxy()  const   {  return fRefProxy; }
   const ROOT::TSchemaRuleSet *GetSchemaRules() const;
   ROOT::TSchemaRuleSet *GetSchemaRules(Bool_t create = kFALSE);
   const char        *GetSharedLibs();
   ShowMembersFunc_t  GetShowMembersWrapper() const { return fShowMembers; }
   EState             GetState() const { return fState; }
   TClassStreamer    *GetStreamer() const;
   ClassStreamerFunc_t GetStreamerFunc() const;
   ClassConvStreamerFunc_t GetConvStreamerFunc() const;
   const TObjArray          *GetStreamerInfos() const { return fStreamerInfo; }
   TVirtualStreamerInfo     *GetStreamerInfo(Int_t version=0) const;
   TVirtualStreamerInfo     *GetStreamerInfoAbstractEmulated(Int_t version=0) const;
   TVirtualStreamerInfo     *FindStreamerInfoAbstractEmulated(UInt_t checksum) const;
   const type_info   *GetTypeInfo() const { return fTypeInfo; };
   Bool_t             HasDictionary();
   static Bool_t      HasDictionarySelection(const char* clname);
   void               GetMissingDictionaries(THashTable& result, bool recurse = false);
   void               IgnoreTObjectStreamer(Bool_t ignore=kTRUE);
   Bool_t             InheritsFrom(const char *cl) const;
   Bool_t             InheritsFrom(const TClass *cl) const;
   void               InterpretedShowMembers(void* obj, TMemberInspector &insp, Bool_t isTransient);
   Bool_t             IsFolder() const { return kTRUE; }
   Bool_t             IsLoaded() const;
   Bool_t             IsForeign() const;
   Bool_t             IsStartingWithTObject() const;
   Bool_t             IsVersioned() const { return !( GetClassVersion()<=1 && IsForeign() ); }
   Bool_t             IsTObject() const;
   static TClass     *LoadClass(const char *requestedname, Bool_t silent);
   void               ls(Option_t *opt="") const;
   void               MakeCustomMenuList();
   Bool_t             MatchLegacyCheckSum(UInt_t checksum) const;
   void               Move(void *arenaFrom, void *arenaTo) const;
   void              *New(ENewType defConstructor = kClassNew, Bool_t quiet = kFALSE) const;
   void              *New(void *arena, ENewType defConstructor = kClassNew) const;
   void              *NewArray(Long_t nElements, ENewType defConstructor = kClassNew) const;
   void              *NewArray(Long_t nElements, void *arena, ENewType defConstructor = kClassNew) const;
   virtual void       PostLoadCheck();
   Long_t             Property() const;
   Int_t              ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count);
   Int_t              ReadBuffer(TBuffer &b, void *pointer);
   void               RegisterStreamerInfo(TVirtualStreamerInfo *info);
   void               RemoveStreamerInfo(Int_t slot);
   void               ReplaceWith(TClass *newcl) const;
   void               ResetCaches();
   void               ResetClassInfo(Long_t tagnum);
   void               ResetClassInfo();
   void               ResetInstanceCount() { fInstanceCount = fOnHeap = 0; }
   void               ResetMenuList();
   Int_t              Size() const;
   void               SetCanSplit(Int_t splitmode);
   void               SetCollectionProxy(const ROOT::TCollectionProxyInfo&);
   void               SetContextMenuTitle(const char *title);
   void               SetCurrentStreamerInfo(TVirtualStreamerInfo *info);
   void               SetGlobalIsA(IsAGlobalFunc_t);
   void               SetDeclFile(const char *name, int line) { fDeclFileName = name; fDeclFileLine = line; }
   void               SetDelete(ROOT::DelFunc_t deleteFunc);
   void               SetDeleteArray(ROOT::DelArrFunc_t deleteArrayFunc);
   void               SetDirectoryAutoAdd(ROOT::DirAutoAdd_t dirAutoAddFunc);
   void               SetDestructor(ROOT::DesFunc_t destructorFunc);
   void               SetImplFileName(const char *implFileName) { fImplFileName = implFileName; }
   void               SetMerge(ROOT::MergeFunc_t mergeFunc);
   void               SetResetAfterMerge(ROOT::ResetAfterMergeFunc_t resetFunc);
   void               SetNew(ROOT::NewFunc_t newFunc);
   void               SetNewArray(ROOT::NewArrFunc_t newArrayFunc);
   TVirtualStreamerInfo     *SetStreamerInfo(Int_t version, const char *info="");
   void               SetUnloaded();
   Int_t              WriteBuffer(TBuffer &b, void *pointer, const char *info="");

   void               AdoptReferenceProxy(TVirtualRefProxy* proxy);
   void               AdoptStreamer(TClassStreamer *strm);
   void               AdoptMemberStreamer(const char *name, TMemberStreamer *strm);
   void               SetMemberStreamer(const char *name, MemberStreamerFunc_t strm);
   void               SetStreamerFunc(ClassStreamerFunc_t strm);
   void               SetConvStreamerFunc(ClassConvStreamerFunc_t strm);

   // Function to retrieve the TClass object and dictionary function
   static void           AddClass(TClass *cl);
   static void           AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass* cl);
   static void           RemoveClass(TClass *cl);
   static void           RemoveClassDeclId(TDictionary::DeclId_t id);
   static TClass        *GetClass(const char *name, Bool_t load = kTRUE, Bool_t silent = kFALSE);
   static TClass        *GetClass(const type_info &typeinfo, Bool_t load = kTRUE, Bool_t silent = kFALSE);
   static TClass        *GetClass(ClassInfo_t *info, Bool_t load = kTRUE, Bool_t silent = kFALSE);
   static Bool_t         GetClass(DeclId_t id, std::vector<TClass*> &classes);
   static DictFuncPtr_t  GetDict (const char *cname);
   static DictFuncPtr_t  GetDict (const type_info &info);

   static Int_t       AutoBrowse(TObject *obj, TBrowser *browser);
   static ENewType    IsCallingNew();
   static TClass     *Load(TBuffer &b);
   void               Store(TBuffer &b) const;

   // Pseudo-method apply to the 'obj'. In particular those are used to
   // implement TObject like methods for non-TObject classes

   Int_t              Browse(void *obj, TBrowser *b) const;
   void               DeleteArray(void *ary, Bool_t dtorOnly = kFALSE);
   void               Destructor(void *obj, Bool_t dtorOnly = kFALSE);
   void              *DynamicCast(const TClass *base, void *obj, Bool_t up = kTRUE);
   const void        *DynamicCast(const TClass *base, const void *obj, Bool_t up = kTRUE);
   Bool_t             IsFolder(void *obj) const;

   inline void        Streamer(void *obj, TBuffer &b, const TClass *onfile_class = 0) const
   {
      // Inline for performance, skipping one function call.
#ifdef R__NO_ATOMIC_FUNCTION_POINTER
      fStreamerImpl(this,obj,b,onfile_class);
#else
      auto t = fStreamerImpl.load();
      t(this,obj,b,onfile_class);
#endif
   }

   ClassDef(TClass,0)  //Dictionary containing class information
};

namespace ROOT {

#ifndef R__NO_CLASS_TEMPLATE_SPECIALIZATION
   template <typename T> struct IsPointer { enum { kVal = 0 }; };
   template <typename T> struct IsPointer<T*> { enum { kVal = 1 }; };
#else
   template <typename T> Bool_t IsPointer(const T* /* dummy */) { return false; };
   template <typename T> Bool_t IsPointer(const T** /* dummy */) { return true; };
#endif

   template <typename T> TClass* GetClass(      T* /* dummy */)        { return TClass::GetClass(typeid(T)); }
   template <typename T> TClass* GetClass(const T* /* dummy */)        { return TClass::GetClass(typeid(T)); }

#ifndef R__NO_CLASS_TEMPLATE_SPECIALIZATION
   // This can only be used when the template overload resolution can distringuish between
   // T* and T**
   template <typename T> TClass* GetClass(      T**       /* dummy */) { return GetClass((T*)0); }
   template <typename T> TClass* GetClass(const T**       /* dummy */) { return GetClass((T*)0); }
   template <typename T> TClass* GetClass(      T* const* /* dummy */) { return GetClass((T*)0); }
   template <typename T> TClass* GetClass(const T* const* /* dummy */) { return GetClass((T*)0); }
#endif

   extern TClass *CreateClass(const char *cname, Version_t id,
                              const char *dfil, const char *ifil,
                              Int_t dl, Int_t il);
}

#endif // ROOT_TClass
 TClass.h:1
 TClass.h:2
 TClass.h:3
 TClass.h:4
 TClass.h:5
 TClass.h:6
 TClass.h:7
 TClass.h:8
 TClass.h:9
 TClass.h:10
 TClass.h:11
 TClass.h:12
 TClass.h:13
 TClass.h:14
 TClass.h:15
 TClass.h:16
 TClass.h:17
 TClass.h:18
 TClass.h:19
 TClass.h:20
 TClass.h:21
 TClass.h:22
 TClass.h:23
 TClass.h:24
 TClass.h:25
 TClass.h:26
 TClass.h:27
 TClass.h:28
 TClass.h:29
 TClass.h:30
 TClass.h:31
 TClass.h:32
 TClass.h:33
 TClass.h:34
 TClass.h:35
 TClass.h:36
 TClass.h:37
 TClass.h:38
 TClass.h:39
 TClass.h:40
 TClass.h:41
 TClass.h:42
 TClass.h:43
 TClass.h:44
 TClass.h:45
 TClass.h:46
 TClass.h:47
 TClass.h:48
 TClass.h:49
 TClass.h:50
 TClass.h:51
 TClass.h:52
 TClass.h:53
 TClass.h:54
 TClass.h:55
 TClass.h:56
 TClass.h:57
 TClass.h:58
 TClass.h:59
 TClass.h:60
 TClass.h:61
 TClass.h:62
 TClass.h:63
 TClass.h:64
 TClass.h:65
 TClass.h:66
 TClass.h:67
 TClass.h:68
 TClass.h:69
 TClass.h:70
 TClass.h:71
 TClass.h:72
 TClass.h:73
 TClass.h:74
 TClass.h:75
 TClass.h:76
 TClass.h:77
 TClass.h:78
 TClass.h:79
 TClass.h:80
 TClass.h:81
 TClass.h:82
 TClass.h:83
 TClass.h:84
 TClass.h:85
 TClass.h:86
 TClass.h:87
 TClass.h:88
 TClass.h:89
 TClass.h:90
 TClass.h:91
 TClass.h:92
 TClass.h:93
 TClass.h:94
 TClass.h:95
 TClass.h:96
 TClass.h:97
 TClass.h:98
 TClass.h:99
 TClass.h:100
 TClass.h:101
 TClass.h:102
 TClass.h:103
 TClass.h:104
 TClass.h:105
 TClass.h:106
 TClass.h:107
 TClass.h:108
 TClass.h:109
 TClass.h:110
 TClass.h:111
 TClass.h:112
 TClass.h:113
 TClass.h:114
 TClass.h:115
 TClass.h:116
 TClass.h:117
 TClass.h:118
 TClass.h:119
 TClass.h:120
 TClass.h:121
 TClass.h:122
 TClass.h:123
 TClass.h:124
 TClass.h:125
 TClass.h:126
 TClass.h:127
 TClass.h:128
 TClass.h:129
 TClass.h:130
 TClass.h:131
 TClass.h:132
 TClass.h:133
 TClass.h:134
 TClass.h:135
 TClass.h:136
 TClass.h:137
 TClass.h:138
 TClass.h:139
 TClass.h:140
 TClass.h:141
 TClass.h:142
 TClass.h:143
 TClass.h:144
 TClass.h:145
 TClass.h:146
 TClass.h:147
 TClass.h:148
 TClass.h:149
 TClass.h:150
 TClass.h:151
 TClass.h:152
 TClass.h:153
 TClass.h:154
 TClass.h:155
 TClass.h:156
 TClass.h:157
 TClass.h:158
 TClass.h:159
 TClass.h:160
 TClass.h:161
 TClass.h:162
 TClass.h:163
 TClass.h:164
 TClass.h:165
 TClass.h:166
 TClass.h:167
 TClass.h:168
 TClass.h:169
 TClass.h:170
 TClass.h:171
 TClass.h:172
 TClass.h:173
 TClass.h:174
 TClass.h:175
 TClass.h:176
 TClass.h:177
 TClass.h:178
 TClass.h:179
 TClass.h:180
 TClass.h:181
 TClass.h:182
 TClass.h:183
 TClass.h:184
 TClass.h:185
 TClass.h:186
 TClass.h:187
 TClass.h:188
 TClass.h:189
 TClass.h:190
 TClass.h:191
 TClass.h:192
 TClass.h:193
 TClass.h:194
 TClass.h:195
 TClass.h:196
 TClass.h:197
 TClass.h:198
 TClass.h:199
 TClass.h:200
 TClass.h:201
 TClass.h:202
 TClass.h:203
 TClass.h:204
 TClass.h:205
 TClass.h:206
 TClass.h:207
 TClass.h:208
 TClass.h:209
 TClass.h:210
 TClass.h:211
 TClass.h:212
 TClass.h:213
 TClass.h:214
 TClass.h:215
 TClass.h:216
 TClass.h:217
 TClass.h:218
 TClass.h:219
 TClass.h:220
 TClass.h:221
 TClass.h:222
 TClass.h:223
 TClass.h:224
 TClass.h:225
 TClass.h:226
 TClass.h:227
 TClass.h:228
 TClass.h:229
 TClass.h:230
 TClass.h:231
 TClass.h:232
 TClass.h:233
 TClass.h:234
 TClass.h:235
 TClass.h:236
 TClass.h:237
 TClass.h:238
 TClass.h:239
 TClass.h:240
 TClass.h:241
 TClass.h:242
 TClass.h:243
 TClass.h:244
 TClass.h:245
 TClass.h:246
 TClass.h:247
 TClass.h:248
 TClass.h:249
 TClass.h:250
 TClass.h:251
 TClass.h:252
 TClass.h:253
 TClass.h:254
 TClass.h:255
 TClass.h:256
 TClass.h:257
 TClass.h:258
 TClass.h:259
 TClass.h:260
 TClass.h:261
 TClass.h:262
 TClass.h:263
 TClass.h:264
 TClass.h:265
 TClass.h:266
 TClass.h:267
 TClass.h:268
 TClass.h:269
 TClass.h:270
 TClass.h:271
 TClass.h:272
 TClass.h:273
 TClass.h:274
 TClass.h:275
 TClass.h:276
 TClass.h:277
 TClass.h:278
 TClass.h:279
 TClass.h:280
 TClass.h:281
 TClass.h:282
 TClass.h:283
 TClass.h:284
 TClass.h:285
 TClass.h:286
 TClass.h:287
 TClass.h:288
 TClass.h:289
 TClass.h:290
 TClass.h:291
 TClass.h:292
 TClass.h:293
 TClass.h:294
 TClass.h:295
 TClass.h:296
 TClass.h:297
 TClass.h:298
 TClass.h:299
 TClass.h:300
 TClass.h:301
 TClass.h:302
 TClass.h:303
 TClass.h:304
 TClass.h:305
 TClass.h:306
 TClass.h:307
 TClass.h:308
 TClass.h:309
 TClass.h:310
 TClass.h:311
 TClass.h:312
 TClass.h:313
 TClass.h:314
 TClass.h:315
 TClass.h:316
 TClass.h:317
 TClass.h:318
 TClass.h:319
 TClass.h:320
 TClass.h:321
 TClass.h:322
 TClass.h:323
 TClass.h:324
 TClass.h:325
 TClass.h:326
 TClass.h:327
 TClass.h:328
 TClass.h:329
 TClass.h:330
 TClass.h:331
 TClass.h:332
 TClass.h:333
 TClass.h:334
 TClass.h:335
 TClass.h:336
 TClass.h:337
 TClass.h:338
 TClass.h:339
 TClass.h:340
 TClass.h:341
 TClass.h:342
 TClass.h:343
 TClass.h:344
 TClass.h:345
 TClass.h:346
 TClass.h:347
 TClass.h:348
 TClass.h:349
 TClass.h:350
 TClass.h:351
 TClass.h:352
 TClass.h:353
 TClass.h:354
 TClass.h:355
 TClass.h:356
 TClass.h:357
 TClass.h:358
 TClass.h:359
 TClass.h:360
 TClass.h:361
 TClass.h:362
 TClass.h:363
 TClass.h:364
 TClass.h:365
 TClass.h:366
 TClass.h:367
 TClass.h:368
 TClass.h:369
 TClass.h:370
 TClass.h:371
 TClass.h:372
 TClass.h:373
 TClass.h:374
 TClass.h:375
 TClass.h:376
 TClass.h:377
 TClass.h:378
 TClass.h:379
 TClass.h:380
 TClass.h:381
 TClass.h:382
 TClass.h:383
 TClass.h:384
 TClass.h:385
 TClass.h:386
 TClass.h:387
 TClass.h:388
 TClass.h:389
 TClass.h:390
 TClass.h:391
 TClass.h:392
 TClass.h:393
 TClass.h:394
 TClass.h:395
 TClass.h:396
 TClass.h:397
 TClass.h:398
 TClass.h:399
 TClass.h:400
 TClass.h:401
 TClass.h:402
 TClass.h:403
 TClass.h:404
 TClass.h:405
 TClass.h:406
 TClass.h:407
 TClass.h:408
 TClass.h:409
 TClass.h:410
 TClass.h:411
 TClass.h:412
 TClass.h:413
 TClass.h:414
 TClass.h:415
 TClass.h:416
 TClass.h:417
 TClass.h:418
 TClass.h:419
 TClass.h:420
 TClass.h:421
 TClass.h:422
 TClass.h:423
 TClass.h:424
 TClass.h:425
 TClass.h:426
 TClass.h:427
 TClass.h:428
 TClass.h:429
 TClass.h:430
 TClass.h:431
 TClass.h:432
 TClass.h:433
 TClass.h:434
 TClass.h:435
 TClass.h:436
 TClass.h:437
 TClass.h:438
 TClass.h:439
 TClass.h:440
 TClass.h:441
 TClass.h:442
 TClass.h:443
 TClass.h:444
 TClass.h:445
 TClass.h:446
 TClass.h:447
 TClass.h:448
 TClass.h:449
 TClass.h:450
 TClass.h:451
 TClass.h:452
 TClass.h:453
 TClass.h:454
 TClass.h:455
 TClass.h:456
 TClass.h:457
 TClass.h:458
 TClass.h:459
 TClass.h:460
 TClass.h:461
 TClass.h:462
 TClass.h:463
 TClass.h:464
 TClass.h:465
 TClass.h:466
 TClass.h:467
 TClass.h:468
 TClass.h:469
 TClass.h:470
 TClass.h:471
 TClass.h:472
 TClass.h:473
 TClass.h:474
 TClass.h:475
 TClass.h:476
 TClass.h:477
 TClass.h:478
 TClass.h:479
 TClass.h:480
 TClass.h:481
 TClass.h:482
 TClass.h:483
 TClass.h:484
 TClass.h:485
 TClass.h:486
 TClass.h:487
 TClass.h:488
 TClass.h:489
 TClass.h:490
 TClass.h:491
 TClass.h:492
 TClass.h:493
 TClass.h:494
 TClass.h:495
 TClass.h:496
 TClass.h:497
 TClass.h:498
 TClass.h:499
 TClass.h:500
 TClass.h:501
 TClass.h:502
 TClass.h:503
 TClass.h:504
 TClass.h:505
 TClass.h:506
 TClass.h:507
 TClass.h:508
 TClass.h:509
 TClass.h:510
 TClass.h:511
 TClass.h:512
 TClass.h:513
 TClass.h:514
 TClass.h:515
 TClass.h:516
 TClass.h:517
 TClass.h:518
 TClass.h:519
 TClass.h:520
 TClass.h:521
 TClass.h:522
 TClass.h:523
 TClass.h:524
 TClass.h:525
 TClass.h:526
 TClass.h:527
 TClass.h:528
 TClass.h:529
 TClass.h:530
 TClass.h:531
 TClass.h:532
 TClass.h:533
 TClass.h:534
 TClass.h:535
 TClass.h:536
 TClass.h:537
 TClass.h:538
 TClass.h:539
 TClass.h:540
 TClass.h:541
 TClass.h:542
 TClass.h:543
 TClass.h:544
 TClass.h:545
 TClass.h:546
 TClass.h:547
 TClass.h:548
 TClass.h:549
 TClass.h:550
 TClass.h:551
 TClass.h:552
 TClass.h:553
 TClass.h:554
 TClass.h:555
 TClass.h:556
 TClass.h:557
 TClass.h:558
 TClass.h:559
 TClass.h:560
 TClass.h:561
 TClass.h:562
 TClass.h:563
 TClass.h:564
 TClass.h:565
 TClass.h:566
 TClass.h:567
 TClass.h:568
 TClass.h:569
 TClass.h:570
 TClass.h:571
 TClass.h:572
 TClass.h:573
 TClass.h:574
 TClass.h:575
 TClass.h:576
 TClass.h:577
 TClass.h:578
 TClass.h:579
 TClass.h:580
 TClass.h:581
 TClass.h:582
 TClass.h:583
 TClass.h:584
 TClass.h:585