Logo ROOT  
Reference Guide
RooLinkedListIter.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * File: $Id: RooLinkedListIter.h,v 1.11 2007/05/11 09:11:30 verkerke Exp $
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 #ifndef ROO_LINKED_LIST_ITER
17 #define ROO_LINKED_LIST_ITER
18 
19 #include "TIterator.h"
20 #include "RooLinkedList.h"
21 
22 #include <memory>
23 #include <stdexcept>
24 #include <assert.h>
25 
26 /// Interface for RooFIter-compatible iterators
28 {
29  public:
30  /// Return next element or nullptr if at end.
31  virtual RooAbsArg * next() = 0;
32  virtual ~GenericRooFIter() {}
33 };
34 
35 ////////////////////////////////////////////////////////////////////////////////////////////
36 /// A one-time forward iterator working on RooLinkedList or RooAbsCollection.
37 /// This wrapper separates the interface visible to the outside from the actual
38 /// implementation of the iterator.
39 class RooFIter final
40 {
41  public:
42  RooFIter(std::unique_ptr<GenericRooFIter> && itImpl) : fIterImpl{std::move(itImpl)} {}
43  RooFIter(const RooFIter &) = delete;
44  RooFIter(RooFIter &&) = default;
45  RooFIter & operator=(const RooFIter &) = delete;
46  RooFIter & operator=(RooFIter &&) = default;
47 
48  /// Return next element or nullptr if at end.
50  return fIterImpl->next();
51  }
52 
53  private:
54  std::unique_ptr<GenericRooFIter> fIterImpl;
55 };
56 
57 ////////////////////////////////////////////////////////////////////////////////////////////
58 /// Implementation of the GenericRooFIter interface for the RooLinkedList
60 {
61  public:
63  RooFIterForLinkedList(const RooLinkedList* list) : fPtr (list->_first) {}
64 
65  /// Return next element in collection
66  RooAbsArg *next() override {
67  if (!fPtr) return nullptr ;
68  TObject* arg = fPtr->_arg ;
69  fPtr = fPtr->_next;
70  return (RooAbsArg*) arg ;
71  }
72 
73  private:
74  const RooLinkedListElem * fPtr{nullptr}; //! Next link element
75 };
76 
77 
78 
79 
80 ////////////////////////////////////////////////////////////////////////////////////////////
81 /// TIterator and GenericRooFIter front end with STL back end.
82 ///
83 /// By default, this iterators counts, at which position the current element should be.
84 /// On request, it does an index access to the underlying collection, and returns the element.
85 /// This happens because the RooLinkedList, which used to be the default collection in RooFit,
86 /// will not invalidate iterators when inserting elements. Since the default is now an STL collection,
87 /// reallocations might invalidate the iterator.
88 ///
89 /// With an iterator that counts, only inserting before or at the iterator position will create problems.
90 /// deal with reallocations while iterating. Therefore, this iterator will also check that the last element
91 /// it was pointing to is the the current element when it is invoked again. This ensures that
92 /// inserting or removing before this iterator does not happen, which was possible with
93 /// the linked list iterators of RooFit.
94 /// When NDEBUG is defined, these checks will disappear.
95 /// \note This is a legacy iterator that only exists to not break old code. Use begin(), end() and
96 /// range-based for loops with RooArgList and RooArgSet.
97 template<class STLContainer>
98 class TIteratorToSTLInterface final : public TIterator , public GenericRooFIter {
99 public:
100 
101  TIteratorToSTLInterface(const STLContainer & container) :
102  TIterator(),
103  GenericRooFIter(),
104  fSTLContainer(container),
105  fIndex(0)
106 #ifdef NDEBUG
107  ,fCurrentElem{nullptr}
108 #else
109  ,fCurrentElem{fSTLContainer.empty() ? nullptr : fSTLContainer.front()}
110 #endif
111  {
112 
113  }
114 
115  TIterator & operator=(const TIterator &) override {
116  throw;
117  }
118 
119  const TCollection *GetCollection() const override {
120  return nullptr;
121  }
122 
123  RooAbsArg * next() override {
124  if (atEnd())
125  return nullptr;
126 #ifdef NDEBUG
127  return fSTLContainer[fIndex++];
128 #else
129  return nextChecked();
130 #endif
131  }
132 
133 
134  TObject * Next() override {
135  return static_cast<TObject*>(next());
136  }
137 
138  void Reset() override {
139  fIndex = 0;
140 #ifndef NDEBUG
141  fCurrentElem = fSTLContainer.empty() ? nullptr : fSTLContainer.front();
142 #endif
143 
144  }
145 
146  Bool_t operator!=(const TIterator & other) const override {
147  const auto * castedOther =
148  dynamic_cast<const TIteratorToSTLInterface<STLContainer>*>(&other);
149  return !castedOther || &fSTLContainer != &(castedOther->fSTLContainer)
150  || fIndex == castedOther->fIndex;
151  }
152 
153  TObject * operator*() const override {
154  if (atEnd())
155  return nullptr;
156 
157  #ifndef NDEBUG
158  assert(fCurrentElem == fSTLContainer[fIndex]);
159  #endif
160 
161  return static_cast<TObject*>(fSTLContainer[fIndex]);
162  }
163 
164 
165 private:
166  bool atEnd() const {
167  return fSTLContainer.empty()
168  || fIndex >= fSTLContainer.size();
169  }
170 
171 
173  RooAbsArg * ret = fSTLContainer.at(fIndex);
174  if (fCurrentElem != nullptr && ret != fCurrentElem) {
175  throw std::logic_error("A RooCollection should not be modified while iterating. "
176  "Only inserting at end is acceptable.");
177  }
178  fCurrentElem = ++fIndex < fSTLContainer.size() ? fSTLContainer[fIndex] : nullptr;
179 
180  return ret;
181  }
182 
183 
184  const STLContainer & fSTLContainer; //!
185  std::size_t fIndex; //!
186  const RooAbsArg * fCurrentElem; //!
187 };
188 
189 
190 
191 
192 ////////////////////////////////////////////////////////////////////////////////////////////
193 /// A wrapper around TIterator derivatives.
194 ///
195 /// It is called RooLinkedListIter because all classes assume that the RooAbsCollections use
196 /// a RooLinkedList, which is not true, any more.
197 /// The purpose of this wrapper is to act on the outside like a RooLinkedListIter, even though
198 /// the underlying implementation may work an a different container, like e.g.
199 /// an STL container. This is needed to not break user code that is using a RooLinkedList or
200 /// a RooAbsCollection.
201 ///
202 /// \note All code using this iterator as an iterator over a RooAbsCollection should move
203 /// to begin() and end() or range-based for loops. These are faster.
204 class RooLinkedListIter final : public TIterator {
205 
206  public:
207  RooLinkedListIter(std::shared_ptr<TIterator> iterImpl) :
208  fIterImpl{std::move(iterImpl)} {
209 
210  }
211 
212  RooLinkedListIter(const RooLinkedListIter &) = delete;
213  RooLinkedListIter(RooLinkedListIter &&) = default;
214  RooLinkedListIter & operator=(const RooLinkedListIter &) = delete;
216 
217  TIterator &operator=(const TIterator & other) override {fIterImpl->operator=(other); return *this;}
218  const TCollection *GetCollection() const override {return nullptr;}
219 
220  TObject * Next() override {return fIterImpl->Next();}
221  void Reset() override {fIterImpl->Reset();}
222  Bool_t operator!=(const TIterator & other) const override {return fIterImpl->operator!=(other);}
223  TObject * operator*() const override {return fIterImpl->operator*();}
224 
225  private:
226  std::shared_ptr<TIterator> fIterImpl; //!
227 };
228 
229 
230 ////////////////////////////////////////////////////////////////////////////////////////////
231 /// Implementation of the actual iterator on RooLinkedLists.
232 ///
233 class RooLinkedListIterImpl final : public TIterator {
234 public:
235 
237  // coverity[UNINIT_CTOR]
238  } ;
239 
240 
242  TIterator(), _list(list), _ptr(forward ? _list->_first : _list->_last),
244  { }
245 
247  TIterator(other), _list(other._list), _ptr(other._ptr),
248  _forward(other._forward)
249  {
250  // Copy constructor
251  }
252 
254 
255  TIterator& operator=(const TIterator& other) {
256 
257  // Iterator assignment operator
258 
259  if (&other==this) return *this ;
260  const RooLinkedListIterImpl* iter = dynamic_cast<const RooLinkedListIterImpl*>(&other) ;
261  if (iter) {
262  _list = iter->_list ;
263  _ptr = iter->_ptr ;
264  _forward = iter->_forward ;
265  }
266  return *this ;
267  }
268 
269  virtual const TCollection *GetCollection() const {
270  // Dummy
271  return 0 ;
272  }
273 
274  virtual TObject *Next() {
275  // Return next element in collection
276  if (!_ptr) return 0 ;
277  TObject* arg = _ptr->_arg ;
278  _ptr = _forward ? _ptr->_next : _ptr->_prev ;
279  return arg ;
280  }
281 
283  // Return next element in collection
284  if (!_ptr) return 0 ;
285  TObject* arg = _ptr->_arg ;
286  _ptr = _forward ? _ptr->_next : _ptr->_prev ;
287  return arg ;
288  }
289 
290 
291  virtual void Reset() {
292  // Return iterator to first element in collection
293  _ptr = _forward ? _list->_first : _list->_last ;
294  }
295 
296  bool operator!=(const TIterator &aIter) const {
297  const RooLinkedListIterImpl *iter(dynamic_cast<const RooLinkedListIterImpl*>(&aIter));
298  if (iter) return (_ptr != iter->_ptr);
299  return false; // for base class we don't implement a comparison
300  }
301 
302  bool operator!=(const RooLinkedListIterImpl &aIter) const {
303  return (_ptr != aIter._ptr);
304  }
305 
306  virtual TObject *operator*() const {
307  // Return element iterator points to
308  return (_ptr ? _ptr->_arg : nullptr);
309  }
310 
311 protected:
312  const RooLinkedList* _list ; //! Collection iterated over
313  const RooLinkedListElem* _ptr ; //! Next link element
314  Bool_t _forward ; //! Iterator direction
315 };
316 
317 
318 
319 
320 #endif
RooFIterForLinkedList::RooFIterForLinkedList
RooFIterForLinkedList(const RooLinkedList *list)
Definition: RooLinkedListIter.h:63
TIteratorToSTLInterface::TIteratorToSTLInterface
TIteratorToSTLInterface(const STLContainer &container)
Definition: RooLinkedListIter.h:101
RooLinkedList::_last
RooLinkedListElem * _last
Link to first element of list.
Definition: RooLinkedList.h:114
TIteratorToSTLInterface::fIndex
std::size_t fIndex
Definition: RooLinkedListIter.h:185
TIteratorToSTLInterface::Reset
void Reset() override
Definition: RooLinkedListIter.h:138
GenericRooFIter::~GenericRooFIter
virtual ~GenericRooFIter()
Definition: RooLinkedListIter.h:46
RooFIterForLinkedList::RooFIterForLinkedList
RooFIterForLinkedList()
Definition: RooLinkedListIter.h:62
TIteratorToSTLInterface::nextChecked
RooAbsArg * nextChecked()
Definition: RooLinkedListIter.h:172
RooLinkedListIterImpl::RooLinkedListIterImpl
RooLinkedListIterImpl(const RooLinkedListIterImpl &other)
Definition: RooLinkedListIter.h:246
RooLinkedListIterImpl::operator!=
bool operator!=(const TIterator &aIter) const
Compare two iterator objects.
Definition: RooLinkedListIter.h:296
RooFIterForLinkedList::next
RooAbsArg * next() override
Return next element in collection.
Definition: RooLinkedListIter.h:66
RooLinkedListIterImpl::operator!=
bool operator!=(const RooLinkedListIterImpl &aIter) const
Definition: RooLinkedListIter.h:302
RooLinkedListIter::operator=
TIterator & operator=(const TIterator &other) override
Definition: RooLinkedListIter.h:217
RooLinkedListIterImpl::operator=
TIterator & operator=(const TIterator &other)
Definition: RooLinkedListIter.h:255
TIteratorToSTLInterface::GetCollection
const TCollection * GetCollection() const override
Definition: RooLinkedListIter.h:119
RooFIter::fIterImpl
std::unique_ptr< GenericRooFIter > fIterImpl
Definition: RooLinkedListIter.h:54
RooLinkedListElem::_next
RooLinkedListElem * _next
Definition: RooLinkedListElem.h:91
RooFIter::RooFIter
RooFIter(std::unique_ptr< GenericRooFIter > &&itImpl)
Definition: RooLinkedListIter.h:42
TIteratorToSTLInterface::operator=
TIterator & operator=(const TIterator &) override
Definition: RooLinkedListIter.h:115
TIteratorToSTLInterface::atEnd
bool atEnd() const
Definition: RooLinkedListIter.h:166
RooLinkedListIter::GetCollection
const TCollection * GetCollection() const override
Definition: RooLinkedListIter.h:218
RooLinkedListIter::Next
TObject * Next() override
Definition: RooLinkedListIter.h:220
bool
TIterator
Definition: TIterator.h:30
GenericRooFIter::next
virtual RooAbsArg * next()=0
Return next element or nullptr if at end.
TIteratorToSTLInterface::operator*
TObject * operator*() const override
Return current object or nullptr.
Definition: RooLinkedListIter.h:153
RooLinkedListElem
Definition: RooLinkedListElem.h:30
RooLinkedListIterImpl::RooLinkedListIterImpl
RooLinkedListIterImpl()
Definition: RooLinkedListIter.h:236
TIteratorToSTLInterface::fCurrentElem
const RooAbsArg * fCurrentElem
Definition: RooLinkedListIter.h:186
TIteratorToSTLInterface::Next
TObject * Next() override
Definition: RooLinkedListIter.h:134
RooLinkedListIterImpl::_ptr
const RooLinkedListElem * _ptr
Collection iterated over.
Definition: RooLinkedListIter.h:313
RooLinkedListIterImpl::RooLinkedListIterImpl
RooLinkedListIterImpl(const RooLinkedList *list, Bool_t forward)
Definition: RooLinkedListIter.h:241
RooLinkedListIter::Reset
void Reset() override
Definition: RooLinkedListIter.h:221
RooLinkedList::_first
RooLinkedListElem * _first
Definition: RooLinkedList.h:113
RooLinkedListIterImpl::NextNV
TObject * NextNV()
Definition: RooLinkedListIter.h:282
RooLinkedListIter
A wrapper around TIterator derivatives.
Definition: RooLinkedListIter.h:204
RooFIterForLinkedList
Implementation of the GenericRooFIter interface for the RooLinkedList.
Definition: RooLinkedListIter.h:59
TIterator.h
RooFIter::operator=
RooFIter & operator=(const RooFIter &)=delete
RooFIter
A one-time forward iterator working on RooLinkedList or RooAbsCollection.
Definition: RooLinkedListIter.h:39
RooLinkedListIterImpl::GetCollection
virtual const TCollection * GetCollection() const
Definition: RooLinkedListIter.h:269
RooLinkedList
Definition: RooLinkedList.h:35
RooLinkedListIterImpl::_forward
Bool_t _forward
Next link element.
Definition: RooLinkedListIter.h:314
RooFIter::next
RooAbsArg * next()
Return next element or nullptr if at end.
Definition: RooLinkedListIter.h:49
RooLinkedListIter::fIterImpl
std::shared_ptr< TIterator > fIterImpl
Definition: RooLinkedListIter.h:226
RooLinkedListElem::_prev
RooLinkedListElem * _prev
Definition: RooLinkedListElem.h:90
RooLinkedListIterImpl
Implementation of the actual iterator on RooLinkedLists.
Definition: RooLinkedListIter.h:233
NDEBUG
#define NDEBUG
Definition: precommondefs.h:41
TIteratorToSTLInterface::fSTLContainer
const STLContainer & fSTLContainer
Definition: RooLinkedListIter.h:184
GenericRooFIter
Interface for RooFIter-compatible iterators.
Definition: RooLinkedListIter.h:27
RooLinkedListIter::operator!=
Bool_t operator!=(const TIterator &other) const override
Compare two iterator objects.
Definition: RooLinkedListIter.h:222
RooLinkedListIterImpl::Reset
virtual void Reset()
Definition: RooLinkedListIter.h:291
TIteratorToSTLInterface::operator!=
Bool_t operator!=(const TIterator &other) const override
Compare two iterator objects.
Definition: RooLinkedListIter.h:146
RooLinkedListIter::operator*
TObject * operator*() const override
Return current object or nullptr.
Definition: RooLinkedListIter.h:223
RooLinkedListIter::RooLinkedListIter
RooLinkedListIter(std::shared_ptr< TIterator > iterImpl)
Definition: RooLinkedListIter.h:207
RooLinkedListIterImpl::operator*
virtual TObject * operator*() const
Return current object or nullptr.
Definition: RooLinkedListIter.h:306
RooLinkedList.h
TMVA::DNN::forward
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:546
RooFIterForLinkedList::fPtr
const RooLinkedListElem * fPtr
Definition: RooLinkedListIter.h:74
TObject
Definition: TObject.h:37
RooLinkedListElem::_arg
TObject * _arg
Definition: RooLinkedListElem.h:92
RooLinkedListIterImpl::_list
const RooLinkedList * _list
Definition: RooLinkedListIter.h:312
RooLinkedListIterImpl::Next
virtual TObject * Next()
Definition: RooLinkedListIter.h:274
RooLinkedListIter::operator=
RooLinkedListIter & operator=(const RooLinkedListIter &)=delete
RooAbsArg
Definition: RooAbsArg.h:73
TCollection
Definition: TCollection.h:63
TIteratorToSTLInterface::next
RooAbsArg * next() override
Return next element or nullptr if at end.
Definition: RooLinkedListIter.h:123
TIteratorToSTLInterface
TIterator and GenericRooFIter front end with STL back end.
Definition: RooLinkedListIter.h:98
RooLinkedListIterImpl::~RooLinkedListIterImpl
virtual ~RooLinkedListIterImpl()
Definition: RooLinkedListIter.h:253