Logo ROOT  
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
18Small helper class to generically acquire and release iterators.
19*/
20
22#include "TError.h"
23
25{
26private:
27 TVirtualCollectionIterators() = delete; // Intentionally unimplemented.
28 TVirtualCollectionIterators(const TVirtualCollectionIterators&) = delete; // Intentionally unimplemented.
29
30public:
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())
44
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);
54 } else {
55 ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
56 }
57 }
58
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);
78 }
79 }
80};
81
82
84{
85protected:
87
88 // The actual implementation.
89 class RegularIterator;
90 class VectorIterator;
91
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
108public:
109
110 virtual void *Next() = 0;
111
112 virtual void* operator*() const = 0;
113
114 virtual operator bool() const = 0;
115
117
118 static TGenericCollectionIterator *New(void *collection, TVirtualCollectionProxy *proxy);
119};
120
123
125 void *fCurrent;
126 bool fStarted : 1;
127
128public:
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),
134 {
135 }
136
137 void *Next() {
138 fStarted = kTRUE;
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
159public:
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();
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{
195public:
201
202private:
203 TVirtualCollectionPtrIterators(); // Intentionally unimplemented.
204 TVirtualCollectionPtrIterators(const TVirtualCollectionPtrIterators&); // Intentionally unimplemented.
205
208
210
213
215 private:
216 TInternalIterator &operator=(const TInternalIterator&); // intentionally not implemented
217 public:
219 TInternalIterator(const TInternalIterator &source) : fCopy(source.fCopy),fDelete(source.fDelete),fNext(source.fNext),fIter(0) {}
220
224
225 void *fIter;
226 };
227
230
231public:
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
240 fBegin( &(fRawBeginBuffer[0]) ),
241 fEnd( &(fRawEndBuffer[0]) )
242 {
243 // memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
244 // memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
245 if (proxy) {
248
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
267 }
271 fEnd = &fEndBuffer;
272 }
273
275 {
276 if (fAllocated) {
277 // assert(end != endbuf);
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{
318private:
319 TVirtualVectorIterators(const TVirtualVectorIterators&); // Intentionally unimplemented.
320
321public:
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
332 {
333 // fCreateIterators = proxy->GetFunctionCreateIterators();
334 }
335
337 {
338 // fCreateIterators = creator;
339 }
340
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
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
void Fatal(const char *location, const char *msgfmt,...)
RegularIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file)
VectorIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file)
TVirtualCollectionIterators fIterators
TGenericCollectionIterator(const TGenericCollectionIterator &)=delete
TGenericCollectionIterator & operator++()
static TGenericCollectionIterator * New(void *collection, TVirtualCollectionProxy *proxy)
virtual void * operator*() const =0
virtual void * Next()=0
TGenericCollectionIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file=kTRUE)
Small helper class to generically acquire and release iterators.
TVirtualCollectionIterators(const TVirtualCollectionIterators &)=delete
TVirtualCollectionProxy::CreateIterators_t CreateIterators_t
void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
TVirtualCollectionIterators(TVirtualCollectionProxy *proxy, Bool_t read_from_file=kTRUE)
TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t
char fEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize]
TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct)
char fBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize]
void(* CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
void *(* CopyIterator_t)(void *dest, const void *source)
void *(* Next_t)(void *iter, const void *end)
virtual Int_t GetCollectionType() const =0
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
void(* DeleteTwoIterators_t)(void *begin, void *end)
void(* DeleteIterator_t)(void *iter)
static const Int_t fgIteratorArenaSize
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read=kTRUE)=0
virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read=kTRUE)=0
TVirtualCollectionPtrIterators(const TVirtualCollectionPtrIterators &)
TVirtualCollectionProxy::DeleteIterator_t Delete_t
char fRawBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize]
TVirtualCollectionProxy::CreateIterators_t CreateIterators_t
TVirtualCollectionProxy::Next_t Next_t
void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
TVirtualCollectionPtrIterators(TVirtualCollectionProxy *proxy)
TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t
TVirtualCollectionProxy::CopyIterator_t Copy_t
char fRawEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize]
static void * Next(void *iter, const void *end)
static void * CopyIterator(void *dest, const void *source)
@ kSTLvector
Definition: ESTLType.h:30
TInternalIterator & operator=(const TInternalIterator &)
TVirtualVectorIterators(TVirtualCollectionProxy *)
void CreateIterators(void *collection)
TVirtualCollectionProxy::CreateIterators_t CreateIterators_t
TVirtualVectorIterators(const TVirtualVectorIterators &)
TVirtualVectorIterators(CreateIterators_t)
#define dest(otri, vertexptr)
Definition: triangle.c:1040