#ifndef ROOT_TTreeReaderValue
#define ROOT_TTreeReaderValue
#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TDictionary
#include "TDictionary.h"
#endif
#ifndef ROOT_TBranchProxy
#include "TBranchProxy.h"
#endif
#include <type_traits>
class TBranch;
class TBranchElement;
class TLeaf;
class TTreeReader;
namespace ROOT {
namespace Internal {
class TTreeReaderValueBase {
public:
enum ESetupStatus {
kSetupNotSetup = -7,
kSetupTreeDestructed = -8,
kSetupMakeClassModeMismatch = -7,
kSetupMissingCounterBranch = -6,
kSetupMissingBranch = -5,
kSetupInternalError = -4,
kSetupMissingDictionary = -3,
kSetupMismatch = -2,
kSetupNotACollection = -1,
kSetupMatch = 0,
kSetupMatchBranch = 0,
kSetupNoCheck = 5,
kSetupMatchLeaf = 6
};
enum EReadStatus {
kReadSuccess = 0,
kReadNothingYet,
kReadError
};
EReadStatus ProxyRead();
Bool_t IsValid() const { return fProxy && 0 == (int)fSetupStatus && 0 == (int)fReadStatus; }
ESetupStatus GetSetupStatus() const { return fSetupStatus; }
virtual EReadStatus GetReadStatus() const { return fReadStatus; }
TLeaf* GetLeaf() { return fLeaf; }
void* GetAddress();
const char* GetBranchName() const { return fBranchName; }
virtual ~TTreeReaderValueBase();
protected:
TTreeReaderValueBase(TTreeReader* reader = 0, const char* branchname = 0, TDictionary* dict = 0);
TTreeReaderValueBase(const TTreeReaderValueBase&);
TTreeReaderValueBase& operator=(const TTreeReaderValueBase&);
void RegisterWithTreeReader();
void NotifyNewTree(TTree* newTree);
virtual void CreateProxy();
const char* GetBranchDataType(TBranch* branch,
TDictionary* &dict) const;
virtual const char* GetDerivedTypeName() const = 0;
Detail::TBranchProxy* GetProxy() const { return fProxy; }
void MarkTreeReaderUnavailable() { fTreeReader = 0; fSetupStatus = kSetupTreeDestructed; }
static std::string GetElementTypeName(const std::type_info& ti);
TString fBranchName;
TString fLeafName;
TTreeReader* fTreeReader;
TDictionary* fDict;
Detail::TBranchProxy* fProxy;
TLeaf* fLeaf;
ESetupStatus fSetupStatus;
EReadStatus fReadStatus;
std::vector<Long64_t> fStaticClassOffsets;
friend class ::TTreeReader;
};
}
}
template <typename T>
class TTreeReaderValue: public ROOT::Internal::TTreeReaderValueBase {
public:
using NonConstT_t = typename std::remove_const<T>::type;
TTreeReaderValue() {}
TTreeReaderValue(TTreeReader& tr, const char* branchname):
TTreeReaderValueBase(&tr, branchname,
TDictionary::GetDictionary(typeid(NonConstT_t))) {}
T* Get() {
if (!fProxy){
Error("Get()", "Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?");
return 0;
}
void *address = GetAddress();
return fProxy->IsaPointer() ? *(T**)address : (T*)address; }
T* operator->() { return Get(); }
T& operator*() { return *Get(); }
protected:
virtual const char* GetDerivedTypeName() const {
static const std::string sElementTypeName = GetElementTypeName(typeid(T));
return sElementTypeName.data();
}
};
#endif // ROOT_TTreeReaderValue