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.
39class 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.
97template<class STLContainer>
98class TIteratorToSTLInterface final : public TIterator , public GenericRooFIter {
99public:
100
101 TIteratorToSTLInterface(const STLContainer & container) :
102 TIterator(),
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
159 #endif
160
161 return static_cast<TObject*>(fSTLContainer[fIndex]);
162 }
163
164
165private:
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; //!
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.
204class RooLinkedListIter final : public TIterator {
205
206 public:
207 RooLinkedListIter(std::shared_ptr<TIterator> iterImpl) :
208 fIterImpl{std::move(iterImpl)} {
209
210 }
211
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///
233class RooLinkedListIterImpl final : public TIterator {
234public:
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
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
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
311protected:
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
bool Bool_t
Definition: RtypesCore.h:61
Interface for RooFIter-compatible iterators.
virtual ~GenericRooFIter()
virtual RooAbsArg * next()=0
Return next element or nullptr if at end.
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:73
Implementation of the GenericRooFIter interface for the RooLinkedList.
RooAbsArg * next() override
Return next element in collection.
RooFIterForLinkedList(const RooLinkedList *list)
const RooLinkedListElem * fPtr
A one-time forward iterator working on RooLinkedList or RooAbsCollection.
RooFIter(RooFIter &&)=default
RooFIter(const RooFIter &)=delete
RooAbsArg * next()
Return next element or nullptr if at end.
RooFIter & operator=(const RooFIter &)=delete
std::unique_ptr< GenericRooFIter > fIterImpl
RooFIter(std::unique_ptr< GenericRooFIter > &&itImpl)
RooFIter & operator=(RooFIter &&)=default
RooLinkedListElem is an link element for the RooLinkedList class.
RooLinkedListElem * _prev
RooLinkedListElem * _next
Implementation of the actual iterator on RooLinkedLists.
virtual TObject * operator*() const
Return current object or nullptr.
TIterator & operator=(const TIterator &other)
bool operator!=(const RooLinkedListIterImpl &aIter) const
const RooLinkedList * _list
virtual const TCollection * GetCollection() const
Bool_t _forward
Next link element.
RooLinkedListIterImpl(const RooLinkedListIterImpl &other)
bool operator!=(const TIterator &aIter) const
Compare two iterator objects.
RooLinkedListIterImpl(const RooLinkedList *list, Bool_t forward)
virtual TObject * Next()
const RooLinkedListElem * _ptr
Collection iterated over.
A wrapper around TIterator derivatives.
RooLinkedListIter(std::shared_ptr< TIterator > iterImpl)
RooLinkedListIter & operator=(RooLinkedListIter &&)=default
const TCollection * GetCollection() const override
RooLinkedListIter(RooLinkedListIter &&)=default
RooLinkedListIter(const RooLinkedListIter &)=delete
void Reset() override
Bool_t operator!=(const TIterator &other) const override
Compare two iterator objects.
TObject * Next() override
TObject * operator*() const override
Return current object or nullptr.
RooLinkedListIter & operator=(const RooLinkedListIter &)=delete
TIterator & operator=(const TIterator &other) override
std::shared_ptr< TIterator > fIterImpl
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:35
RooLinkedListElem * _last
Link to first element of list.
RooLinkedListElem * _first
Collection abstract base class.
Definition: TCollection.h:63
TIterator and GenericRooFIter front end with STL back end.
TObject * Next() override
RooAbsArg * next() override
Return next element or nullptr if at end.
const RooAbsArg * fCurrentElem
TIterator & operator=(const TIterator &) override
Bool_t operator!=(const TIterator &other) const override
Compare two iterator objects.
TIteratorToSTLInterface(const STLContainer &container)
TObject * operator*() const override
Return current object or nullptr.
const TCollection * GetCollection() const override
const STLContainer & fSTLContainer
Iterator abstract base class.
Definition: TIterator.h:30
Mother of all ROOT objects.
Definition: TObject.h:37
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:546
#define NDEBUG
Definition: precommondefs.h:41