@@ -78,10 +78,28 @@ class TTreeReader: public TObject {
7878 fEntry (entry), fReader (&reader) {}
7979
8080 // / Compare two iterators for equality.
81- bool operator ==(const Iterator_t& lhs) const {
81+ bool operator ==(const Iterator_t & lhs) const {
8282 // From C++14: value initialized (past-end) it compare equal.
83- if (!IsValid () && !lhs.IsValid ()) return true ;
84- return fEntry == lhs.fEntry && fReader == lhs.fReader ;
83+ if (!IsValid () && !lhs.IsValid ())
84+ return true ;
85+ // The iterators refer to different readers
86+ if (fReader != lhs.fReader )
87+ return false ;
88+ // #16249: range based loop and the tree has zero entries
89+ // as well as analogous cases.
90+ // Getting the number of events can have a cost, for example in
91+ // case of chains of remote files accessible with high latency.
92+ // However, it is reasonable to assume that if iterators are
93+ // being compared is because an iteration is taking place,
94+ // therefore such cost has to be paid anyway, it's just
95+ // anticipated.
96+ if (fReader ->GetTree ()->GetEntriesFast () == 0 && fEntry == 0 && !lhs.IsValid ()) {
97+ return true ;
98+ }
99+ if (lhs.fReader ->GetTree ()->GetEntriesFast () == 0 && lhs.fEntry == 0 && !IsValid ()) {
100+ return true ;
101+ }
102+ return fEntry == lhs.fEntry ;
85103 }
86104
87105 // / Compare two iterators for inequality.
@@ -241,7 +259,7 @@ class TTreeReader: public TObject {
241259 return Iterator_t (*this , 0 );
242260 }
243261 // / Return an iterator beyond the last TTree entry.
244- Iterator_t end () const { return Iterator_t (); }
262+ Iterator_t end () { return Iterator_t (* this , - 1 ); }
245263
246264protected:
247265 using NamedProxies_t = std::unordered_map<std::string, std::unique_ptr<ROOT::Internal::TNamedBranchProxy>>;
0 commit comments