File indexing completed on 2025-01-18 10:12:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_TVirtualCollectionIterators
0013 #define ROOT_TVirtualCollectionIterators
0014
0015
0016
0017
0018
0019
0020
0021 #include "TVirtualCollectionProxy.h"
0022 #include "TError.h"
0023 #include <vector>
0024
0025 class TVirtualCollectionIterators
0026 {
0027 private:
0028 TVirtualCollectionIterators() = delete;
0029 TVirtualCollectionIterators(const TVirtualCollectionIterators&) = delete;
0030
0031 public:
0032
0033
0034
0035
0036 typedef TVirtualCollectionProxy::CreateIterators_t CreateIterators_t;
0037 typedef TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t;
0038
0039 char fBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
0040 char fEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
0041 void *fBegin;
0042 void *fEnd;
0043 CreateIterators_t fCreateIterators;
0044 DeleteTwoIterators_t fDeleteTwoIterators;
0045
0046 TVirtualCollectionIterators(TVirtualCollectionProxy *proxy, Bool_t read_from_file = kTRUE) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(nullptr), fDeleteTwoIterators(nullptr)
0047 {
0048
0049
0050
0051
0052 if (proxy) {
0053 fCreateIterators = proxy->GetFunctionCreateIterators(read_from_file);
0054 fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators(read_from_file);
0055 } else {
0056 ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
0057 }
0058 }
0059
0060 TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(creator), fDeleteTwoIterators(destruct)
0061 {
0062
0063 }
0064
0065 inline void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
0066 {
0067
0068
0069 fCreateIterators(collection, &fBegin, &fEnd, proxy);
0070 }
0071
0072 inline ~TVirtualCollectionIterators()
0073 {
0074
0075
0076 if (fBegin != &(fBeginBuffer[0])) {
0077
0078 fDeleteTwoIterators(fBegin,fEnd);
0079 }
0080 }
0081 };
0082
0083
0084 class TGenericCollectionIterator
0085 {
0086 protected:
0087 TVirtualCollectionIterators fIterators;
0088
0089
0090 class RegularIterator;
0091 class VectorIterator;
0092
0093 TGenericCollectionIterator() = delete;
0094 TGenericCollectionIterator(const TGenericCollectionIterator&) = delete;
0095
0096 TGenericCollectionIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file = kTRUE) :
0097 fIterators(proxy,read_from_file)
0098 {
0099
0100
0101 fIterators.CreateIterators(collection,proxy);
0102 }
0103
0104 virtual ~TGenericCollectionIterator()
0105 {
0106
0107 }
0108
0109 public:
0110
0111 virtual void *Next() = 0;
0112
0113 virtual void* operator*() const = 0;
0114
0115 virtual operator bool() const = 0;
0116
0117 TGenericCollectionIterator& operator++() { Next(); return *this; }
0118
0119 static TGenericCollectionIterator *New(void *collection, TVirtualCollectionProxy *proxy);
0120 };
0121
0122 class TGenericCollectionIterator::RegularIterator : public TGenericCollectionIterator {
0123 typedef TVirtualCollectionProxy::Next_t Next_t;
0124
0125 Next_t fNext;
0126 void *fCurrent;
0127 bool fStarted : 1;
0128
0129 public:
0130 RegularIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file) :
0131 TGenericCollectionIterator(collection,proxy,read_from_file),
0132 fNext( proxy->GetFunctionNext(read_from_file) ),
0133 fCurrent(nullptr),
0134 fStarted(kFALSE)
0135 {
0136 }
0137
0138 void *Next() override {
0139 fStarted = kTRUE;
0140 fCurrent = fNext(fIterators.fBegin,fIterators.fEnd);
0141 return fCurrent;
0142 }
0143
0144 void* operator*() const override { return fCurrent; }
0145
0146 operator bool() const override { return fStarted ? fCurrent != nullptr : kTRUE; }
0147
0148 };
0149
0150 class TGenericCollectionIterator::VectorIterator : public TGenericCollectionIterator {
0151
0152 ULong_t fIncrement;
0153 Bool_t fHasPointer;
0154
0155 inline void *GetValue() const {
0156 if ((bool)*this) return fHasPointer ? *(void**)fIterators.fBegin : fIterators.fBegin;
0157 else return nullptr;
0158 }
0159
0160 public:
0161 VectorIterator(void *collection, TVirtualCollectionProxy *proxy, Bool_t read_from_file) :
0162 TGenericCollectionIterator(collection,proxy,read_from_file),
0163 fIncrement(proxy->GetIncrement()),
0164 fHasPointer(proxy->HasPointers())
0165 {
0166 }
0167
0168 void *Next() override {
0169 if ( ! (bool)*this ) return nullptr;
0170 void *result = GetValue();
0171 fIterators.fBegin = ((char*)fIterators.fBegin) + fIncrement;
0172 return result;
0173 }
0174
0175 void* operator*() const override { return GetValue(); }
0176
0177 operator bool() const override { return fIterators.fBegin != fIterators.fEnd; }
0178
0179 };
0180
0181 inline TGenericCollectionIterator *TGenericCollectionIterator::New(void *collection, TVirtualCollectionProxy *proxy)
0182 {
0183 if (proxy->GetCollectionType() == ROOT::kSTLvector) {
0184 return new VectorIterator(collection, proxy, kFALSE);
0185 } else {
0186 return new RegularIterator(collection, proxy, kFALSE);
0187 }
0188 }
0189
0190
0191
0192
0193
0194 class TVirtualCollectionPtrIterators
0195 {
0196 public:
0197 typedef TVirtualCollectionProxy::Next_t Next_t;
0198 typedef TVirtualCollectionProxy::CopyIterator_t Copy_t;
0199 typedef TVirtualCollectionProxy::CreateIterators_t CreateIterators_t;
0200 typedef TVirtualCollectionProxy::DeleteIterator_t Delete_t;
0201 typedef TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t;
0202
0203 private:
0204 TVirtualCollectionPtrIterators();
0205 TVirtualCollectionPtrIterators(const TVirtualCollectionPtrIterators&);
0206
0207 CreateIterators_t fCreateIterators;
0208 DeleteTwoIterators_t fDeleteTwoIterators;
0209
0210 Bool_t fAllocated;
0211
0212 char fRawBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
0213 char fRawEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
0214
0215 struct TInternalIterator {
0216 private:
0217 TInternalIterator &operator=(const TInternalIterator&);
0218 public:
0219 TInternalIterator() : fCopy(nullptr), fDelete(nullptr), fNext(nullptr), fIter(nullptr) {}
0220 TInternalIterator(const TInternalIterator &source) : fCopy(source.fCopy), fDelete(source.fDelete), fNext(source.fNext), fIter(nullptr) {}
0221
0222 Copy_t fCopy;
0223 Delete_t fDelete;
0224 Next_t fNext;
0225
0226 void *fIter;
0227 };
0228
0229 TInternalIterator fBeginBuffer;
0230 TInternalIterator fEndBuffer;
0231
0232 public:
0233
0234
0235
0236
0237 void *fBegin;
0238 void *fEnd;
0239
0240 TVirtualCollectionPtrIterators(TVirtualCollectionProxy *proxy) : fCreateIterators(nullptr), fDeleteTwoIterators(nullptr), fAllocated(kFALSE),
0241 fBegin( &(fRawBeginBuffer[0]) ),
0242 fEnd( &(fRawEndBuffer[0]) )
0243 {
0244
0245
0246 if (proxy) {
0247 fCreateIterators = proxy->GetFunctionCreateIterators();
0248 fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
0249
0250 fEndBuffer.fCopy = fBeginBuffer.fCopy = proxy->GetFunctionCopyIterator();
0251 fEndBuffer.fNext = fBeginBuffer.fNext = proxy->GetFunctionNext();
0252 fEndBuffer.fDelete = fBeginBuffer.fDelete = proxy->GetFunctionDeleteIterator();
0253 } else {
0254 ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
0255 }
0256 }
0257
0258 inline void CreateIterators(void *collection, TVirtualCollectionProxy *proxy)
0259 {
0260
0261
0262 fBegin = &(fRawBeginBuffer[0]);
0263 fEnd = &(fRawEndBuffer[0]);
0264 fCreateIterators(collection, &fBegin, &fEnd, proxy);
0265 if (fBegin != &(fRawBeginBuffer[0])) {
0266
0267 fAllocated = kTRUE;
0268 }
0269 fBeginBuffer.fIter = fBegin;
0270 fEndBuffer.fIter = fEnd;
0271 fBegin = &fBeginBuffer;
0272 fEnd = &fEndBuffer;
0273 }
0274
0275 inline ~TVirtualCollectionPtrIterators()
0276 {
0277 if (fAllocated) {
0278
0279 fDeleteTwoIterators(fBeginBuffer.fIter,fEndBuffer.fIter);
0280 }
0281 }
0282
0283 static void *Next(void *iter, const void *end)
0284 {
0285 TInternalIterator *internal_iter = (TInternalIterator*) iter;
0286 TInternalIterator *internal_end = (TInternalIterator*) end;
0287
0288 void **ptr = (void**)internal_iter->fNext(internal_iter->fIter,internal_end->fIter);
0289 if(ptr) return *ptr;
0290 else return nullptr;
0291 }
0292
0293 static void DeleteIterator(void *iter)
0294 {
0295 TInternalIterator *internal_iter = (TInternalIterator*) iter;
0296 if (internal_iter->fDelete) {
0297 internal_iter->fDelete(internal_iter->fIter);
0298 }
0299 }
0300
0301 static void *CopyIterator(void *dest, const void *source)
0302 {
0303 TInternalIterator *internal_source = (TInternalIterator*)source;
0304 TInternalIterator *internal_dest = new TInternalIterator(*internal_source);
0305
0306 void *newiter = internal_source->fCopy(dest,internal_source->fIter);
0307 if (newiter == dest) {
0308 internal_dest->fDelete = nullptr;
0309 }
0310 internal_dest->fIter = newiter;
0311 return internal_dest;
0312 }
0313 };
0314
0315
0316
0317 struct TVirtualVectorIterators
0318 {
0319 private:
0320 TVirtualVectorIterators(const TVirtualVectorIterators&);
0321
0322 public:
0323
0324
0325
0326
0327 typedef TVirtualCollectionProxy::CreateIterators_t CreateIterators_t;
0328
0329 void *fBegin;
0330 void *fEnd;
0331
0332 TVirtualVectorIterators(TVirtualCollectionProxy * ) : fBegin(nullptr), fEnd(nullptr)
0333 {
0334
0335 }
0336
0337 TVirtualVectorIterators(CreateIterators_t ) : fBegin(nullptr), fEnd(nullptr)
0338 {
0339
0340 }
0341
0342 TVirtualVectorIterators() : fBegin(nullptr), fEnd(nullptr)
0343 {
0344
0345 }
0346
0347 inline void CreateIterators(void *collection)
0348 {
0349
0350
0351
0352
0353 std::vector<char> *vec = (std::vector<char>*)collection;
0354 if (vec->empty()) {
0355 fBegin = nullptr;
0356 fEnd = nullptr;
0357 return;
0358 }
0359 fBegin= &(*vec->begin());
0360 #ifdef R__VISUAL_CPLUSPLUS
0361 fEnd = &(*(vec->end()-1)) + 1;
0362 #else
0363
0364 fEnd = &(*vec->end());
0365 #endif
0366
0367 }
0368 };
0369
0370 #endif
0371