// @(#)root/tree:$Id$
// Author: Rene Brun   12/01/96

/*************************************************************************
 * 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_TLeaf
#define ROOT_TLeaf


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TLeaf                                                                //
//                                                                      //
// A TTree object is a list of TBranch.                                 //
// A TBranch object is a list of TLeaf.                                 //
// A TLeaf describes the branch data types.                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


#ifndef ROOT_TBranch
#include "TBranch.h"
#endif
#ifndef ROOT_Riosfwd
#include "Riosfwd.h"
#endif

class TClonesArray;
class TBrowser;

class TLeaf : public TNamed {

protected:

   Int_t       fNdata;           //! Number of elements in fAddress data buffer
   Int_t       fLen;             //  Number of fixed length elements
   Int_t       fLenType;         //  Number of bytes for this data type
   Int_t       fOffset;          //  Offset in ClonesArray object (if one)
   Bool_t      fIsRange;         //  (=kTRUE if leaf has a range, kFALSE otherwise)
   Bool_t      fIsUnsigned;      //  (=kTRUE if unsigned, kFALSE otherwise)
   TLeaf      *fLeafCount;       //  Pointer to Leaf count if variable length (we do not own the counter)
   TBranch    *fBranch;          //! Pointer to supporting branch (we do not own the branch)

   TLeaf(const TLeaf&);
   TLeaf& operator=(const TLeaf&);

  template <typename T> struct GetValueHelper {
    static T Exec(const TLeaf *leaf, Int_t i = 0) { return leaf->GetValue(i); }
  };

public:
   enum {
      kIndirectAddress = BIT(11), // Data member is a pointer to an array of basic types.
      kNewValue = BIT(12)         // Set if we own the value buffer and so must delete it ourselves.
   };

   TLeaf();
   TLeaf(TBranch *parent, const char* name, const char* type);
   virtual ~TLeaf();

   virtual void     Browse(TBrowser* b);
   virtual void     Export(TClonesArray*, Int_t) {}
   virtual void     FillBasket(TBuffer& b);
   TBranch         *GetBranch() const { return fBranch; }
   virtual TLeaf   *GetLeafCount() const { return fLeafCount; }
   virtual TLeaf   *GetLeafCounter(Int_t& countval) const;
   virtual Int_t    GetLen() const;
   virtual Int_t    GetLenStatic() const { return fLen; }
   virtual Int_t    GetLenType() const { return fLenType; }
   virtual Int_t    GetMaximum() const { return 0; }
   virtual Int_t    GetMinimum() const { return 0; }
   virtual Int_t    GetNdata() const { return fNdata; }
   virtual Int_t    GetOffset() const { return fOffset; }
   virtual void    *GetValuePointer() const { return 0; }
   virtual const char *GetTypeName() const { return ""; }
  
   virtual Double_t GetValue(Int_t i = 0) const;
   virtual Long64_t GetValueLong64(Int_t i = 0) const { return GetValue(i); } //overload only when it matters.
   virtual LongDouble_t GetValueLongDouble(Int_t i = 0) const { return GetValue(i); } // overload only when it matters.
   template <typename T > T GetTypedValue(Int_t i = 0) const { return GetValueHelper<T>::Exec(this, i); }

   virtual void     Import(TClonesArray*, Int_t) {}
   virtual Bool_t   IsOnTerminalBranch() const { return kTRUE; }
   virtual Bool_t   IsRange() const { return fIsRange; }
   virtual Bool_t   IsUnsigned() const { return fIsUnsigned; }
   virtual void     PrintValue(Int_t i = 0) const;
   virtual void     ReadBasket(TBuffer&) {}
   virtual void     ReadBasketExport(TBuffer&, TClonesArray*, Int_t) {}
   virtual void     ReadValue(std::istream& /*s*/, Char_t /*delim*/ = ' ') {
      Error("ReadValue", "Not implemented!");
   }
           Int_t    ResetAddress(void* add, Bool_t destructor = kFALSE);
   virtual void     SetAddress(void* add = 0);
   virtual void     SetBranch(TBranch* branch) { fBranch = branch; }
   virtual void     SetLeafCount(TLeaf* leaf);
   virtual void     SetLen(Int_t len = 1) { fLen = len; }
   virtual void     SetOffset(Int_t offset = 0) { fOffset = offset; }
   virtual void     SetRange(Bool_t range = kTRUE) { fIsRange = range; }
   virtual void     SetUnsigned() { fIsUnsigned = kTRUE; }

   ClassDef(TLeaf,2);  //Leaf: description of a Branch data type
};


template <> struct TLeaf::GetValueHelper<Long64_t> {
   static Long64_t Exec(const TLeaf *leaf, Int_t i = 0) { return leaf->GetValueLong64(i); }
};
template <> struct TLeaf::GetValueHelper<ULong64_t> {
   static ULong64_t Exec(const TLeaf *leaf, Int_t i = 0) { return (ULong64_t)leaf->GetValueLong64(i); }
};
template <> struct TLeaf::GetValueHelper<LongDouble_t> {
   static LongDouble_t Exec(const TLeaf *leaf, Int_t i = 0) { return leaf->GetValueLongDouble(i); }
};


inline Double_t TLeaf::GetValue(Int_t /*i = 0*/) const { return 0.0; }
inline void     TLeaf::PrintValue(Int_t /* i = 0*/) const {}
inline void     TLeaf::SetAddress(void* /* add = 0 */) {}

#endif
 TLeaf.h:1
 TLeaf.h:2
 TLeaf.h:3
 TLeaf.h:4
 TLeaf.h:5
 TLeaf.h:6
 TLeaf.h:7
 TLeaf.h:8
 TLeaf.h:9
 TLeaf.h:10
 TLeaf.h:11
 TLeaf.h:12
 TLeaf.h:13
 TLeaf.h:14
 TLeaf.h:15
 TLeaf.h:16
 TLeaf.h:17
 TLeaf.h:18
 TLeaf.h:19
 TLeaf.h:20
 TLeaf.h:21
 TLeaf.h:22
 TLeaf.h:23
 TLeaf.h:24
 TLeaf.h:25
 TLeaf.h:26
 TLeaf.h:27
 TLeaf.h:28
 TLeaf.h:29
 TLeaf.h:30
 TLeaf.h:31
 TLeaf.h:32
 TLeaf.h:33
 TLeaf.h:34
 TLeaf.h:35
 TLeaf.h:36
 TLeaf.h:37
 TLeaf.h:38
 TLeaf.h:39
 TLeaf.h:40
 TLeaf.h:41
 TLeaf.h:42
 TLeaf.h:43
 TLeaf.h:44
 TLeaf.h:45
 TLeaf.h:46
 TLeaf.h:47
 TLeaf.h:48
 TLeaf.h:49
 TLeaf.h:50
 TLeaf.h:51
 TLeaf.h:52
 TLeaf.h:53
 TLeaf.h:54
 TLeaf.h:55
 TLeaf.h:56
 TLeaf.h:57
 TLeaf.h:58
 TLeaf.h:59
 TLeaf.h:60
 TLeaf.h:61
 TLeaf.h:62
 TLeaf.h:63
 TLeaf.h:64
 TLeaf.h:65
 TLeaf.h:66
 TLeaf.h:67
 TLeaf.h:68
 TLeaf.h:69
 TLeaf.h:70
 TLeaf.h:71
 TLeaf.h:72
 TLeaf.h:73
 TLeaf.h:74
 TLeaf.h:75
 TLeaf.h:76
 TLeaf.h:77
 TLeaf.h:78
 TLeaf.h:79
 TLeaf.h:80
 TLeaf.h:81
 TLeaf.h:82
 TLeaf.h:83
 TLeaf.h:84
 TLeaf.h:85
 TLeaf.h:86
 TLeaf.h:87
 TLeaf.h:88
 TLeaf.h:89
 TLeaf.h:90
 TLeaf.h:91
 TLeaf.h:92
 TLeaf.h:93
 TLeaf.h:94
 TLeaf.h:95
 TLeaf.h:96
 TLeaf.h:97
 TLeaf.h:98
 TLeaf.h:99
 TLeaf.h:100
 TLeaf.h:101
 TLeaf.h:102
 TLeaf.h:103
 TLeaf.h:104
 TLeaf.h:105
 TLeaf.h:106
 TLeaf.h:107
 TLeaf.h:108
 TLeaf.h:109
 TLeaf.h:110
 TLeaf.h:111
 TLeaf.h:112
 TLeaf.h:113
 TLeaf.h:114
 TLeaf.h:115
 TLeaf.h:116
 TLeaf.h:117
 TLeaf.h:118
 TLeaf.h:119
 TLeaf.h:120
 TLeaf.h:121
 TLeaf.h:122
 TLeaf.h:123
 TLeaf.h:124
 TLeaf.h:125
 TLeaf.h:126