Logo ROOT   6.08/07
Reference Guide
TVirtualCollectionIterators.h
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Philippe Canal 20/08/2010
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers and al. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TVirtualCollectionIterators
13 #define ROOT_TVirtualCollectionIterators
14 
15 /**
16 \class TVirtualCollectionIterators
17 \ingroup IO
18 Small helper class to generically acquire and release iterators.
19 */
20 
21 #ifndef ROOT_TVirtualCollectionProxy
23 #endif
24 #ifndef ROOT_TError
25 #include "TError.h"
26 #endif
27 
29 {
30 private:
31  TVirtualCollectionIterators(); // Intentionally unimplemented.
32  TVirtualCollectionIterators(const TVirtualCollectionIterators&); // Intentionally unimplemented.
33 
34 public:
35  // Note when the collection is a vector, fBegin and fEnd points to
36  // the start and end of the memory content rather than to the address
37  // of iterators (saving one dereference when being used).
38 
41 
44  void *fBegin; // Pointer to the starting iterator (collection->begin())
45  void *fEnd; // Pointer to the ending iterator (collection->end())
46  CreateIterators_t fCreateIterators;
47  DeleteTwoIterators_t fDeleteTwoIterators;
48 
49  TVirtualCollectionIterators(TVirtualCollectionProxy *proxy, Bool_t read_from_file = kTRUE) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(0), fDeleteTwoIterators(0)
50  {
51  // Constructor given a collection proxy.
52 
53  // memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
54  // memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
55  if (proxy) {
56  fCreateIterators = proxy->GetFunctionCreateIterators(read_from_file);
57  fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators(read_from_file);
58  } else {
59  ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
60  }
61  }
62 
63  TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(creator), fDeleteTwoIterators(destruct)
64  {
65  // Constructor given the creation and delete routines.
66  }
67 
68  inline void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
69  {
70  // Initialize the fBegin and fEnd iterators.
71 
72  fCreateIterators(collection, &fBegin, &fEnd, proxy);
73  }
74 
76  {
77  // Destructor.
78 
79  if (fBegin != &(fBeginBuffer[0])) {
80  // assert(end != endbuf);
81  fDeleteTwoIterators(fBegin,fEnd);
82  }
83  }
84 };
85 
86 
88 {
89 protected:
91 
92  // The actual implementation.
93  class RegularIterator;
94  class VectorIterator;
95 
96  TGenericCollectionIterator() = delete;
98 
99  TGenericCollectionIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file = kTRUE) :
100  fIterators(proxy,read_from_file)
101  {
102  // Regular constructor.
103 
104  fIterators.CreateIterators(collection,proxy);
105  }
106 
108  {
109  // Regular destructor.
110  }
111 
112 public:
113 
114  virtual void *Next() = 0;
115 
116  virtual void* operator*() const = 0;
117 
118  virtual operator bool() const = 0;
119 
120  TGenericCollectionIterator& operator++() { Next(); return *this; }
121 
122  static TGenericCollectionIterator *New(void *collection, TVirtualCollectionProxy *proxy);
123 };
124 
127 
128  Next_t fNext;
129  void *fCurrent;
130  bool fStarted : 1;
131 
132 public:
133  RegularIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file) :
134  TGenericCollectionIterator(collection,proxy,read_from_file),
135  fNext( proxy->GetFunctionNext(read_from_file) ),
136  fCurrent(0),
137  fStarted(kFALSE)
138  {
139  }
140 
141  void *Next() {
142  fStarted = kTRUE;
143  fCurrent = fNext(fIterators.fBegin,fIterators.fEnd);
144  return fCurrent;
145  }
146 
147  virtual void* operator*() const { return fCurrent; }
148 
149  operator bool() const { return fStarted ? fCurrent != 0 : kTRUE; }
150 
151 };
152 
154 
157 
158  inline void *GetValue() const {
159  if ((bool)*this) return fHasPointer ? *(void**)fIterators.fBegin : fIterators.fBegin;
160  else return 0;
161  }
162 
163 public:
164  VectorIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file) :
165  TGenericCollectionIterator(collection,proxy,read_from_file),
166  fIncrement(proxy->GetIncrement()),
167  fHasPointer(proxy->HasPointers())
168  {
169  }
170 
171  void *Next() {
172  if ( ! (bool)*this ) return 0;
173  void *result = GetValue();
174  fIterators.fBegin = ((char*)fIterators.fBegin) + fIncrement;
175  return result;
176  }
177 
178  virtual void* operator*() const { return GetValue(); }
179 
180  operator bool() const { return fIterators.fBegin != fIterators.fEnd; }
181 
182 };
183 
185 {
186  if (proxy->GetCollectionType() == ROOT::kSTLvector) {
187  return new VectorIterator(collection, proxy, kFALSE);
188  } else {
189  return new RegularIterator(collection, proxy, kFALSE);
190  }
191 }
192 
193 /**
194 \class TVirtualCollectionPtrIterators
195 \ingroup IO
196 */
198 {
199 public:
205 
206 private:
207  TVirtualCollectionPtrIterators(); // Intentionally unimplemented.
208  TVirtualCollectionPtrIterators(const TVirtualCollectionPtrIterators&); // Intentionally unimplemented.
209 
210  CreateIterators_t fCreateIterators;
211  DeleteTwoIterators_t fDeleteTwoIterators;
212 
214 
217 
219  private:
220  TInternalIterator &operator=(const TInternalIterator&); // intentionally not implemented
221  public:
222  TInternalIterator() : fCopy(0),fDelete(0),fNext(0),fIter(0) {}
223  TInternalIterator(const TInternalIterator &source) : fCopy(source.fCopy),fDelete(source.fDelete),fNext(source.fNext),fIter(0) {}
224 
225  Copy_t fCopy;
226  Delete_t fDelete;
227  Next_t fNext;
228 
229  void *fIter;
230  };
231 
234 
235 public:
236  // Note when the collection is a vector, fBegin and fEnd points to
237  // the start and end of the memory content rather than to the address
238  // of iterators (saving one dereference when being used).
239 
240  void *fBegin; // Pointer to the starting iterator (collection->begin())
241  void *fEnd; // Pointer to the ending iterator (collection->end())
242 
243  TVirtualCollectionPtrIterators(TVirtualCollectionProxy *proxy) : fCreateIterators(0), fDeleteTwoIterators(0), fAllocated(kFALSE),
244  fBegin( &(fRawBeginBuffer[0]) ),
245  fEnd( &(fRawEndBuffer[0]) )
246  {
247  // memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
248  // memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
249  if (proxy) {
250  fCreateIterators = proxy->GetFunctionCreateIterators();
251  fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
252 
253  fEndBuffer.fCopy = fBeginBuffer.fCopy = proxy->GetFunctionCopyIterator();
254  fEndBuffer.fNext = fBeginBuffer.fNext = proxy->GetFunctionNext();
255  fEndBuffer.fDelete = fBeginBuffer.fDelete = proxy->GetFunctionDeleteIterator();
256  } else {
257  ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
258  }
259  }
260 
261  inline void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
262  {
263  // Initialize the fBegin and fEnd iterators.
264 
265  fBegin = &(fRawBeginBuffer[0]);
266  fEnd = &(fRawEndBuffer[0]);
267  fCreateIterators(collection, &fBegin, &fEnd, proxy);
268  if (fBegin != &(fRawBeginBuffer[0])) {
269  // The iterator where too large to buffer in the buffer
270  fAllocated = kTRUE;
271  }
272  fBeginBuffer.fIter = fBegin;
273  fEndBuffer.fIter = fEnd;
274  fBegin = &fBeginBuffer;
275  fEnd = &fEndBuffer;
276  }
277 
279  {
280  if (fAllocated) {
281  // assert(end != endbuf);
282  fDeleteTwoIterators(fBeginBuffer.fIter,fEndBuffer.fIter);
283  }
284  }
285 
286  static void *Next(void *iter, const void *end)
287  {
288  TInternalIterator *internal_iter = (TInternalIterator*) iter;
289  TInternalIterator *internal_end = (TInternalIterator*) end;
290 
291  void **ptr = (void**)internal_iter->fNext(internal_iter->fIter,internal_end->fIter);
292  if(ptr) return *ptr;
293  else return 0;
294  }
295 
296  static void DeleteIterator(void *iter)
297  {
298  TInternalIterator *internal_iter = (TInternalIterator*) iter;
299  if (internal_iter->fDelete) {
300  internal_iter->fDelete(internal_iter->fIter);
301  }
302  }
303 
304  static void *CopyIterator(void *dest, const void *source)
305  {
306  TInternalIterator *internal_source = (TInternalIterator*)source;
307  TInternalIterator *internal_dest = new TInternalIterator(*internal_source);
308 
309  void *newiter = internal_source->fCopy(dest,internal_source->fIter);
310  if (newiter == dest) {
311  internal_dest->fDelete = 0;
312  }
313  internal_dest->fIter = newiter;
314  return internal_dest;
315  }
316 };
317 
318 // Specialization of TVirtualCollectionIterators when we know the collection
319 // to be a vector (hence there is nothing to delete at the end).
321 {
322 private:
323  TVirtualVectorIterators(const TVirtualVectorIterators&); // Intentionally unimplemented.
324 
325 public:
326  // Note when the collection is a vector, fBegin and fEnd points to
327  // the start and end of the memory content rather than to the address
328  // of iterators (saving one dereference when being used).
329 
331 
332  void *fBegin; // Pointer to the starting iterator (collection->begin())
333  void *fEnd; // Pointer to the ending iterator (collection->end())
334 
335  TVirtualVectorIterators(TVirtualCollectionProxy * /* proxy */) : fBegin(0), fEnd(0)
336  {
337  // fCreateIterators = proxy->GetFunctionCreateIterators();
338  }
339 
340  TVirtualVectorIterators(CreateIterators_t /* creator */) : fBegin(0), fEnd(0)
341  {
342  // fCreateIterators = creator;
343  }
344 
345  TVirtualVectorIterators() : fBegin(0), fEnd(0)
346  {
347  // Default constructor.
348  }
349 
350  inline void CreateIterators(void *collection)
351  {
352  // Initialize the fBegin and fEnd iterators.
353 
354  // We can safely assume that the std::vector layout does not really depend on
355  // the content!
356  std::vector<char> *vec = (std::vector<char>*)collection;
357  if (vec->empty()) {
358  fBegin = 0;
359  fEnd = 0;
360  return;
361  }
362  fBegin= &(*vec->begin());
363 #ifdef R__VISUAL_CPLUSPLUS
364  fEnd = &(*(vec->end()-1)) + 1; // On windows we can not dererence the end iterator at all.
365 #else
366  // coverity[past_the_end] Safe on other platforms
367  fEnd = &(*vec->end());
368 #endif
369  //fCreateIterators(collection, &fBegin, &fEnd);
370  }
371 };
372 
373 #endif // ROOT_TVirtualCollectionIterators
374 
virtual Int_t GetCollectionType() const =0
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
void CreateIterators(void *collection)
void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
void Fatal(const char *location, const char *msgfmt,...)
static void * CopyIterator(void *dest, const void *source)
TGenericCollectionIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file=kTRUE)
TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t
static void * Next(void *iter, const void *end)
RegularIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file)
TVirtualCollectionIterators(TVirtualCollectionProxy *proxy, Bool_t read_from_file=kTRUE)
TVirtualCollectionProxy::CreateIterators_t CreateIterators_t
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read=kTRUE)=0
void *(* CopyIterator_t)(void *dest, const void *source)
void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
void(* DeleteIterator_t)(void *iter)
TVirtualCollectionPtrIterators(TVirtualCollectionProxy *proxy)
static TGenericCollectionIterator * New(void *collection, TVirtualCollectionProxy *proxy)
TVirtualVectorIterators(TVirtualCollectionProxy *)
char fEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize]
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
TVirtualCollectionProxy::CreateIterators_t CreateIterators_t
char fBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize]
VectorIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file)
Small helper class to generically acquire and release iterators.
void(* CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
TTime operator*(const TTime &t1, const TTime &t2)
Definition: TTime.h:87
TVirtualCollectionProxy::CopyIterator_t Copy_t
static const Int_t fgIteratorArenaSize
TVirtualVectorIterators(CreateIterators_t)
TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t
TVirtualCollectionProxy::CreateIterators_t CreateIterators_t
TVirtualCollectionProxy::DeleteIterator_t Delete_t
TVirtualCollectionProxy::Next_t Next_t
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read=kTRUE)=0
TGenericCollectionIterator & operator++()
#define dest(otri, vertexptr)
Definition: triangle.c:1040
void *(* Next_t)(void *iter, const void *end)
double result[121]
TVirtualCollectionIterators fIterators
TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct)
const Bool_t kTRUE
Definition: Rtypes.h:91
void(* DeleteTwoIterators_t)(void *begin, void *end)