Logo ROOT   6.14/05
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 
22 #include "TError.h"
23 
25 {
26 private:
27  TVirtualCollectionIterators(); // Intentionally unimplemented.
28  TVirtualCollectionIterators(const TVirtualCollectionIterators&); // Intentionally unimplemented.
29 
30 public:
31  // Note when the collection is a vector, fBegin and fEnd points to
32  // the start and end of the memory content rather than to the address
33  // of iterators (saving one dereference when being used).
34 
37 
40  void *fBegin; // Pointer to the starting iterator (collection->begin())
41  void *fEnd; // Pointer to the ending iterator (collection->end())
42  CreateIterators_t fCreateIterators;
43  DeleteTwoIterators_t fDeleteTwoIterators;
44 
45  TVirtualCollectionIterators(TVirtualCollectionProxy *proxy, Bool_t read_from_file = kTRUE) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(0), fDeleteTwoIterators(0)
46  {
47  // Constructor given a collection proxy.
48 
49  // memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
50  // memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
51  if (proxy) {
52  fCreateIterators = proxy->GetFunctionCreateIterators(read_from_file);
53  fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators(read_from_file);
54  } else {
55  ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
56  }
57  }
58 
59  TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(creator), fDeleteTwoIterators(destruct)
60  {
61  // Constructor given the creation and delete routines.
62  }
63 
64  inline void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
65  {
66  // Initialize the fBegin and fEnd iterators.
67 
68  fCreateIterators(collection, &fBegin, &fEnd, proxy);
69  }
70 
72  {
73  // Destructor.
74 
75  if (fBegin != &(fBeginBuffer[0])) {
76  // assert(end != endbuf);
77  fDeleteTwoIterators(fBegin,fEnd);
78  }
79  }
80 };
81 
82 
84 {
85 protected:
87 
88  // The actual implementation.
89  class RegularIterator;
90  class VectorIterator;
91 
92  TGenericCollectionIterator() = delete;
94 
95  TGenericCollectionIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file = kTRUE) :
96  fIterators(proxy,read_from_file)
97  {
98  // Regular constructor.
99 
100  fIterators.CreateIterators(collection,proxy);
101  }
102 
104  {
105  // Regular destructor.
106  }
107 
108 public:
109 
110  virtual void *Next() = 0;
111 
112  virtual void* operator*() const = 0;
113 
114  virtual operator bool() const = 0;
115 
116  TGenericCollectionIterator& operator++() { Next(); return *this; }
117 
118  static TGenericCollectionIterator *New(void *collection, TVirtualCollectionProxy *proxy);
119 };
120 
123 
124  Next_t fNext;
125  void *fCurrent;
126  bool fStarted : 1;
127 
128 public:
129  RegularIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file) :
130  TGenericCollectionIterator(collection,proxy,read_from_file),
131  fNext( proxy->GetFunctionNext(read_from_file) ),
132  fCurrent(0),
133  fStarted(kFALSE)
134  {
135  }
136 
137  void *Next() {
138  fStarted = kTRUE;
139  fCurrent = fNext(fIterators.fBegin,fIterators.fEnd);
140  return fCurrent;
141  }
142 
143  virtual void* operator*() const { return fCurrent; }
144 
145  operator bool() const { return fStarted ? fCurrent != 0 : kTRUE; }
146 
147 };
148 
150 
153 
154  inline void *GetValue() const {
155  if ((bool)*this) return fHasPointer ? *(void**)fIterators.fBegin : fIterators.fBegin;
156  else return 0;
157  }
158 
159 public:
160  VectorIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file) :
161  TGenericCollectionIterator(collection,proxy,read_from_file),
162  fIncrement(proxy->GetIncrement()),
163  fHasPointer(proxy->HasPointers())
164  {
165  }
166 
167  void *Next() {
168  if ( ! (bool)*this ) return 0;
169  void *result = GetValue();
170  fIterators.fBegin = ((char*)fIterators.fBegin) + fIncrement;
171  return result;
172  }
173 
174  virtual void* operator*() const { return GetValue(); }
175 
176  operator bool() const { return fIterators.fBegin != fIterators.fEnd; }
177 
178 };
179 
181 {
182  if (proxy->GetCollectionType() == ROOT::kSTLvector) {
183  return new VectorIterator(collection, proxy, kFALSE);
184  } else {
185  return new RegularIterator(collection, proxy, kFALSE);
186  }
187 }
188 
189 /**
190 \class TVirtualCollectionPtrIterators
191 \ingroup IO
192 */
194 {
195 public:
201 
202 private:
203  TVirtualCollectionPtrIterators(); // Intentionally unimplemented.
204  TVirtualCollectionPtrIterators(const TVirtualCollectionPtrIterators&); // Intentionally unimplemented.
205 
206  CreateIterators_t fCreateIterators;
207  DeleteTwoIterators_t fDeleteTwoIterators;
208 
210 
213 
215  private:
216  TInternalIterator &operator=(const TInternalIterator&); // intentionally not implemented
217  public:
218  TInternalIterator() : fCopy(0),fDelete(0),fNext(0),fIter(0) {}
219  TInternalIterator(const TInternalIterator &source) : fCopy(source.fCopy),fDelete(source.fDelete),fNext(source.fNext),fIter(0) {}
220 
221  Copy_t fCopy;
222  Delete_t fDelete;
223  Next_t fNext;
224 
225  void *fIter;
226  };
227 
230 
231 public:
232  // Note when the collection is a vector, fBegin and fEnd points to
233  // the start and end of the memory content rather than to the address
234  // of iterators (saving one dereference when being used).
235 
236  void *fBegin; // Pointer to the starting iterator (collection->begin())
237  void *fEnd; // Pointer to the ending iterator (collection->end())
238 
239  TVirtualCollectionPtrIterators(TVirtualCollectionProxy *proxy) : fCreateIterators(0), fDeleteTwoIterators(0), fAllocated(kFALSE),
240  fBegin( &(fRawBeginBuffer[0]) ),
241  fEnd( &(fRawEndBuffer[0]) )
242  {
243  // memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
244  // memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
245  if (proxy) {
246  fCreateIterators = proxy->GetFunctionCreateIterators();
247  fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
248 
249  fEndBuffer.fCopy = fBeginBuffer.fCopy = proxy->GetFunctionCopyIterator();
250  fEndBuffer.fNext = fBeginBuffer.fNext = proxy->GetFunctionNext();
251  fEndBuffer.fDelete = fBeginBuffer.fDelete = proxy->GetFunctionDeleteIterator();
252  } else {
253  ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
254  }
255  }
256 
257  inline void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
258  {
259  // Initialize the fBegin and fEnd iterators.
260 
261  fBegin = &(fRawBeginBuffer[0]);
262  fEnd = &(fRawEndBuffer[0]);
263  fCreateIterators(collection, &fBegin, &fEnd, proxy);
264  if (fBegin != &(fRawBeginBuffer[0])) {
265  // The iterator where too large to buffer in the buffer
266  fAllocated = kTRUE;
267  }
268  fBeginBuffer.fIter = fBegin;
269  fEndBuffer.fIter = fEnd;
270  fBegin = &fBeginBuffer;
271  fEnd = &fEndBuffer;
272  }
273 
275  {
276  if (fAllocated) {
277  // assert(end != endbuf);
278  fDeleteTwoIterators(fBeginBuffer.fIter,fEndBuffer.fIter);
279  }
280  }
281 
282  static void *Next(void *iter, const void *end)
283  {
284  TInternalIterator *internal_iter = (TInternalIterator*) iter;
285  TInternalIterator *internal_end = (TInternalIterator*) end;
286 
287  void **ptr = (void**)internal_iter->fNext(internal_iter->fIter,internal_end->fIter);
288  if(ptr) return *ptr;
289  else return 0;
290  }
291 
292  static void DeleteIterator(void *iter)
293  {
294  TInternalIterator *internal_iter = (TInternalIterator*) iter;
295  if (internal_iter->fDelete) {
296  internal_iter->fDelete(internal_iter->fIter);
297  }
298  }
299 
300  static void *CopyIterator(void *dest, const void *source)
301  {
302  TInternalIterator *internal_source = (TInternalIterator*)source;
303  TInternalIterator *internal_dest = new TInternalIterator(*internal_source);
304 
305  void *newiter = internal_source->fCopy(dest,internal_source->fIter);
306  if (newiter == dest) {
307  internal_dest->fDelete = 0;
308  }
309  internal_dest->fIter = newiter;
310  return internal_dest;
311  }
312 };
313 
314 // Specialization of TVirtualCollectionIterators when we know the collection
315 // to be a vector (hence there is nothing to delete at the end).
317 {
318 private:
319  TVirtualVectorIterators(const TVirtualVectorIterators&); // Intentionally unimplemented.
320 
321 public:
322  // Note when the collection is a vector, fBegin and fEnd points to
323  // the start and end of the memory content rather than to the address
324  // of iterators (saving one dereference when being used).
325 
327 
328  void *fBegin; // Pointer to the starting iterator (collection->begin())
329  void *fEnd; // Pointer to the ending iterator (collection->end())
330 
331  TVirtualVectorIterators(TVirtualCollectionProxy * /* proxy */) : fBegin(0), fEnd(0)
332  {
333  // fCreateIterators = proxy->GetFunctionCreateIterators();
334  }
335 
336  TVirtualVectorIterators(CreateIterators_t /* creator */) : fBegin(0), fEnd(0)
337  {
338  // fCreateIterators = creator;
339  }
340 
341  TVirtualVectorIterators() : fBegin(0), fEnd(0)
342  {
343  // Default constructor.
344  }
345 
346  inline void CreateIterators(void *collection)
347  {
348  // Initialize the fBegin and fEnd iterators.
349 
350  // We can safely assume that the std::vector layout does not really depend on
351  // the content!
352  std::vector<char> *vec = (std::vector<char>*)collection;
353  if (vec->empty()) {
354  fBegin = 0;
355  fEnd = 0;
356  return;
357  }
358  fBegin= &(*vec->begin());
359 #ifdef R__VISUAL_CPLUSPLUS
360  fEnd = &(*(vec->end()-1)) + 1; // On windows we can not dererence the end iterator at all.
361 #else
362  // coverity[past_the_end] Safe on other platforms
363  fEnd = &(*vec->end());
364 #endif
365  //fCreateIterators(collection, &fBegin, &fEnd);
366  }
367 };
368 
369 #endif // ROOT_TVirtualCollectionIterators
370 
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
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:85
TVirtualCollectionProxy::CopyIterator_t Copy_t
static const Int_t fgIteratorArenaSize
TVirtualVectorIterators(CreateIterators_t)
const Bool_t kFALSE
Definition: RtypesCore.h:88
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
Binding & operator=(OUT(*fun)(void))
TGenericCollectionIterator & operator++()
#define dest(otri, vertexptr)
Definition: triangle.c:1040
void *(* Next_t)(void *iter, const void *end)
TVirtualCollectionIterators fIterators
TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct)
void(* DeleteTwoIterators_t)(void *begin, void *end)
const Bool_t kTRUE
Definition: RtypesCore.h:87