// @(#)root/tree:$Id$
// Author: Axel Naumann, 2010-08-02

/*************************************************************************
 * Copyright (C) 1995-2013, 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_TTreeReader
#define ROOT_TTreeReader


////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TTreeReader                                                            //
//                                                                        //
// A simple interface for reading trees or chains.                        //
//                                                                        //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#ifndef ROOT_THashTable
#include "THashTable.h"
#endif
#ifndef ROOT_TTree
#include "TTree.h"
#endif
#ifndef ROOT_TTreeReaderUtils
#include "TTreeReaderUtils.h"
#endif

#include <deque>
#include <iterator>

class TDictionary;
class TDirectory;
class TFileCollection;

namespace ROOT {
   class TBranchProxyDirector;
}

class TTreeReader: public TObject {
public:

   // Iterate through the entries of a TTree.
   //
   // This iterator drives the associated TTreeReader; its
   // dereferencing (and actually even the iteration) will
   // set the entry number represented by this iterator.
   // It does not really represent a data element; it simply
   // returns the entry number (or -1 once the end of the tree
   // is reached).
   class Iterator_t:
      public std::iterator<std::input_iterator_tag, const Long64_t, Long64_t> {
   private:
      Long64_t fEntry; // Entry number of the tree referenced by this iterator; -1 is invalid.
      TTreeReader* fReader; // The reader we select the entries on.

      // Whether the iterator points to a valid entry.
      bool IsValid() const { return fEntry >= 0; }

   public:
      // Default-initialize the iterator as "past the end".
      Iterator_t(): fEntry(-1), fReader() {}

      // Initialize the iterator with the reader it steers and a
      // tree entry number; -1 is invalid.
      Iterator_t(TTreeReader& reader, Long64_t entry):
         fEntry(entry), fReader(&reader) {}

      bool operator==(const Iterator_t& lhs) const {
         // Compare two iterators for equality.
         // From C++14: value initialized (past-end) it compare equal.
         if (!IsValid() && !lhs.IsValid()) return true;
         return fEntry == lhs.fEntry && fReader == lhs.fReader;
      }

      bool operator!=(const Iterator_t& lhs) const {
         // Compare two iterators for inequality.
         return !(*this == lhs);
      }

      Iterator_t operator++(int) {
         // Increment the iterator (postfix i++).
         Iterator_t ret = *this;
         this->operator++();
         return ret;
      }

      Iterator_t& operator++() {
         // Increment the iterator (prefix ++i).
         if (IsValid()) {
            ++fEntry;
            // Force validity check of new fEntry.
            this->operator*();
            // Don't set the old entry: op* will if needed, and
            // in most cases it just adds a lot of spinning back
            // and forth: in most cases teh sequence is ++i; *i.
         }
         return *this;
      }

      const Long64_t& operator*() {
         // Set the entry number in the reader and return it.
         if (IsValid()) {
            // If we cannot access that entry, mark the iterator invalid.
            if (fReader->SetEntry(fEntry) != kEntryValid) {
               fEntry = -1;
            }
         }
         // There really is no data in this iterator; return the number.
         return fEntry;
      }

      const Long64_t& operator*() const {
         return **const_cast<Iterator_t*>(this);
      }
   };

   typedef Iterator_t iterator;

   enum EEntryStatus {
      kEntryValid = 0, // data read okay
      kEntryNotLoaded, // no entry has been loaded yet
      kEntryNoTree, // the tree does not exist
      kEntryNotFound, // the tree entry number does not exist
      kEntryChainSetupError, // problem in accessing a chain element, e.g. file without the tree
      kEntryChainFileError, // problem in opening a chain's file
      kEntryDictionaryError, // problem reading dictionary info from tree
   };

   TTreeReader():
      fDirectory(0),
      fEntryStatus(kEntryNoTree),
      fDirector(0)
   {}

   TTreeReader(TTree* tree);
   TTreeReader(const char* keyname, TDirectory* dir = NULL );
   TTreeReader(const char* /*keyname*/, TFileCollection* /*files*/) { Error("TTreeReader()", "Not Implemented!");};

   ~TTreeReader();

   void SetTree(TTree* tree);
   void SetTree(const char* /*keyname*/, TDirectory* /*dir = NULL*/ ) { Error("SetTree()", "Not Implemented!");};
   void SetChain(const char* /*keyname*/, TFileCollection* /*files*/ ) { Error("SetChain()", "Not Implemented!");};

   Bool_t IsChain() const { return TestBit(kBitIsChain); }

   Bool_t Next() { return SetEntry(GetCurrentEntry() + 1) == kEntryValid; }
   EEntryStatus SetEntry(Long64_t entry) { return SetEntryBase(entry, kFALSE); }
   EEntryStatus SetLocalEntry(Long64_t entry) { return SetEntryBase(entry, kTRUE); }

   EEntryStatus GetEntryStatus() const { return fEntryStatus; }

   TTree* GetTree() const { return fTree; }
   Long64_t GetEntries(Bool_t force) const { return fTree ? (force ? fTree->GetEntries() : fTree->GetEntriesFast() ) : -1; }
   Long64_t GetCurrentEntry() const;

   Iterator_t begin() {
      // Return an iterator to the 0th TTree entry.
      return Iterator_t(*this, 0);
   }
   Iterator_t end() const { return Iterator_t(); }

protected:
   void Initialize();
   ROOT::TNamedBranchProxy* FindProxy(const char* branchname) const {
      return (ROOT::TNamedBranchProxy*) fProxies.FindObject(branchname); }
   TCollection* GetProxies() { return &fProxies; }

   void RegisterValueReader(ROOT::TTreeReaderValueBase* reader);
   void DeregisterValueReader(ROOT::TTreeReaderValueBase* reader);

   EEntryStatus SetEntryBase(Long64_t entry, Bool_t local);

private:

   enum EPropertyBits {
      kBitIsChain = BIT(14) // our tree is a chain
   };

   TTree* fTree; // tree that's read
   TDirectory* fDirectory; // directory (or current file for chains)
   EEntryStatus fEntryStatus; // status of most recent read request
   ROOT::TBranchProxyDirector* fDirector; // proxying director, owned
   std::deque<ROOT::TTreeReaderValueBase*> fValues; // readers that use our director
   THashTable   fProxies; //attached ROOT::TNamedBranchProxies; owned

   friend class ROOT::TTreeReaderValueBase;
   friend class ROOT::TTreeReaderArrayBase;

   ClassDef(TTreeReader, 0); // A simple interface to read trees
};

#endif // defined TTreeReader
 TTreeReader.h:1
 TTreeReader.h:2
 TTreeReader.h:3
 TTreeReader.h:4
 TTreeReader.h:5
 TTreeReader.h:6
 TTreeReader.h:7
 TTreeReader.h:8
 TTreeReader.h:9
 TTreeReader.h:10
 TTreeReader.h:11
 TTreeReader.h:12
 TTreeReader.h:13
 TTreeReader.h:14
 TTreeReader.h:15
 TTreeReader.h:16
 TTreeReader.h:17
 TTreeReader.h:18
 TTreeReader.h:19
 TTreeReader.h:20
 TTreeReader.h:21
 TTreeReader.h:22
 TTreeReader.h:23
 TTreeReader.h:24
 TTreeReader.h:25
 TTreeReader.h:26
 TTreeReader.h:27
 TTreeReader.h:28
 TTreeReader.h:29
 TTreeReader.h:30
 TTreeReader.h:31
 TTreeReader.h:32
 TTreeReader.h:33
 TTreeReader.h:34
 TTreeReader.h:35
 TTreeReader.h:36
 TTreeReader.h:37
 TTreeReader.h:38
 TTreeReader.h:39
 TTreeReader.h:40
 TTreeReader.h:41
 TTreeReader.h:42
 TTreeReader.h:43
 TTreeReader.h:44
 TTreeReader.h:45
 TTreeReader.h:46
 TTreeReader.h:47
 TTreeReader.h:48
 TTreeReader.h:49
 TTreeReader.h:50
 TTreeReader.h:51
 TTreeReader.h:52
 TTreeReader.h:53
 TTreeReader.h:54
 TTreeReader.h:55
 TTreeReader.h:56
 TTreeReader.h:57
 TTreeReader.h:58
 TTreeReader.h:59
 TTreeReader.h:60
 TTreeReader.h:61
 TTreeReader.h:62
 TTreeReader.h:63
 TTreeReader.h:64
 TTreeReader.h:65
 TTreeReader.h:66
 TTreeReader.h:67
 TTreeReader.h:68
 TTreeReader.h:69
 TTreeReader.h:70
 TTreeReader.h:71
 TTreeReader.h:72
 TTreeReader.h:73
 TTreeReader.h:74
 TTreeReader.h:75
 TTreeReader.h:76
 TTreeReader.h:77
 TTreeReader.h:78
 TTreeReader.h:79
 TTreeReader.h:80
 TTreeReader.h:81
 TTreeReader.h:82
 TTreeReader.h:83
 TTreeReader.h:84
 TTreeReader.h:85
 TTreeReader.h:86
 TTreeReader.h:87
 TTreeReader.h:88
 TTreeReader.h:89
 TTreeReader.h:90
 TTreeReader.h:91
 TTreeReader.h:92
 TTreeReader.h:93
 TTreeReader.h:94
 TTreeReader.h:95
 TTreeReader.h:96
 TTreeReader.h:97
 TTreeReader.h:98
 TTreeReader.h:99
 TTreeReader.h:100
 TTreeReader.h:101
 TTreeReader.h:102
 TTreeReader.h:103
 TTreeReader.h:104
 TTreeReader.h:105
 TTreeReader.h:106
 TTreeReader.h:107
 TTreeReader.h:108
 TTreeReader.h:109
 TTreeReader.h:110
 TTreeReader.h:111
 TTreeReader.h:112
 TTreeReader.h:113
 TTreeReader.h:114
 TTreeReader.h:115
 TTreeReader.h:116
 TTreeReader.h:117
 TTreeReader.h:118
 TTreeReader.h:119
 TTreeReader.h:120
 TTreeReader.h:121
 TTreeReader.h:122
 TTreeReader.h:123
 TTreeReader.h:124
 TTreeReader.h:125
 TTreeReader.h:126
 TTreeReader.h:127
 TTreeReader.h:128
 TTreeReader.h:129
 TTreeReader.h:130
 TTreeReader.h:131
 TTreeReader.h:132
 TTreeReader.h:133
 TTreeReader.h:134
 TTreeReader.h:135
 TTreeReader.h:136
 TTreeReader.h:137
 TTreeReader.h:138
 TTreeReader.h:139
 TTreeReader.h:140
 TTreeReader.h:141
 TTreeReader.h:142
 TTreeReader.h:143
 TTreeReader.h:144
 TTreeReader.h:145
 TTreeReader.h:146
 TTreeReader.h:147
 TTreeReader.h:148
 TTreeReader.h:149
 TTreeReader.h:150
 TTreeReader.h:151
 TTreeReader.h:152
 TTreeReader.h:153
 TTreeReader.h:154
 TTreeReader.h:155
 TTreeReader.h:156
 TTreeReader.h:157
 TTreeReader.h:158
 TTreeReader.h:159
 TTreeReader.h:160
 TTreeReader.h:161
 TTreeReader.h:162
 TTreeReader.h:163
 TTreeReader.h:164
 TTreeReader.h:165
 TTreeReader.h:166
 TTreeReader.h:167
 TTreeReader.h:168
 TTreeReader.h:169
 TTreeReader.h:170
 TTreeReader.h:171
 TTreeReader.h:172
 TTreeReader.h:173
 TTreeReader.h:174
 TTreeReader.h:175
 TTreeReader.h:176
 TTreeReader.h:177
 TTreeReader.h:178
 TTreeReader.h:179
 TTreeReader.h:180
 TTreeReader.h:181
 TTreeReader.h:182
 TTreeReader.h:183
 TTreeReader.h:184
 TTreeReader.h:185
 TTreeReader.h:186
 TTreeReader.h:187
 TTreeReader.h:188
 TTreeReader.h:189
 TTreeReader.h:190
 TTreeReader.h:191
 TTreeReader.h:192
 TTreeReader.h:193
 TTreeReader.h:194
 TTreeReader.h:195
 TTreeReader.h:196
 TTreeReader.h:197
 TTreeReader.h:198
 TTreeReader.h:199
 TTreeReader.h:200