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