Logo ROOT   6.16/01
Reference Guide
TEmulatedCollectionProxy.cxx
Go to the documentation of this file.
1// @(#)root/io:$Id$
2// Author: Markus Frank 28/10/04
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
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/**
13 \class TEmulatedCollectionProxy
14 \ingroup IO
15
16Streamer around an arbitrary STL like container, which implements basic
17container functionality.
18
19### Note:
20Although this class contains all the setup necessary to deal
21with maps, the map-like functionality is NOT supported.
22For optimization reasons this functionality is put into
23the class TEmulatedMapProxy.
24*/
25
27#include "TStreamerElement.h"
28#include "TStreamerInfo.h"
29#include "TClassEdit.h"
30#include "TError.h"
31#include "TROOT.h"
32#include "Riostream.h"
33
34#include "TVirtualMutex.h" // For R__LOCKGUARD
35#include "TInterpreter.h" // For gInterpreterMutex
36
37//
38// Utility function to allow the creation of a TClass for a std::pair without
39// a dictionary (See end of file for implementation
40//
41
42static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset);
43static TStreamerInfo *R__GenerateTClassForPair(const std::string &f, const std::string &s);
44
47{
48 // Build a Streamer for an emulated vector whose type is 'name'.
50}
51
53 : TGenCollectionProxy(typeid(std::vector<char>), sizeof(std::vector<char>::iterator))
54{
55 // Build a Streamer for a collection whose type is described by 'collectionClass'.
56
57 fName = cl_name;
58 if ( this->TEmulatedCollectionProxy::InitializeEx(silent) ) {
60 }
62}
63
65{
66 // Standard destructor
67 if ( fEnv && fEnv->fObject ) {
68 Clear();
69 }
70}
71
73{
74 // Virtual copy constructor
75
76 if ( !fClass ) Initialize(kFALSE);
77 return new TEmulatedCollectionProxy(*this);
78}
79
80void TEmulatedCollectionProxy::Destructor(void* p, Bool_t dtorOnly) const
81{
82 // Virtual destructor
83
84 if (!p) return;
85 if (!fEnv || fEnv->fObject != p) { // Envoid the cost of TPushPop if we don't need it
86 // FIXME: This is not thread safe.
88 const_cast<TEmulatedCollectionProxy*>(this)->Clear("force");
89 } else {
90 const_cast<TEmulatedCollectionProxy*>(this)->Clear("force");
91 }
92 if (dtorOnly) {
93 ((Cont_t*)p)->~Cont_t();
94 } else {
95 delete (Cont_t*) p;
96 }
97}
98
99void TEmulatedCollectionProxy::DeleteArray(void* p, Bool_t dtorOnly) const
100{
101 // Virtual array destructor
102
103 // Cannot implement this properly, we do not know
104 // how many elements are in the array.
105 Warning("DeleteArray", "Cannot properly delete emulated array of %s at %p, I don't know how many elements it has!", fClass->GetName(), p);
106 if (!dtorOnly) {
107 delete[] (Cont_t*) p;
108 }
109}
110
112{
113 // Proxy initializer
115 if (fClass) return this;
116
117
118 TClass *cl = TClass::GetClass(fName.c_str());
119 fEnv = 0;
120 fKey = 0;
121 if ( cl ) {
122 int nested = 0;
123 std::vector<std::string> inside;
124 fPointers = false;
125 int num = TClassEdit::GetSplit(fName.c_str(),inside,nested);
126 if ( num > 1 ) {
127 std::string nam;
128 if ( inside[0].find("stdext::hash_") != std::string::npos ) {
129 inside[0].replace(3,10,"::");
130 }
131 if ( inside[0].find("__gnu_cxx::hash_") != std::string::npos ) {
132 inside[0].replace(0,16,"std::");
133 }
134 fSTL_type = TClassEdit::STLKind(inside[0]);
135 // Note: an emulated collection proxy is never really associative
136 // since under-neath is actually an array.
137
138 // std::cout << "Initialized " << typeid(*this).name() << ":" << fName << std::endl;
139 auto alignedSize = [](size_t in) {
140 constexpr size_t kSizeOfPtr = sizeof(void*);
141 return in + (kSizeOfPtr - in%kSizeOfPtr)%kSizeOfPtr;
142 };
143 switch ( fSTL_type ) {
144 case ROOT::kSTLmap:
146 nam = "pair<"+inside[1]+","+inside[2];
147 nam += (nam[nam.length()-1]=='>') ? " >" : ">";
148 if (0==TClass::GetClass(nam.c_str())) {
149 // We need to emulate the pair
150 R__GenerateTClassForPair(inside[1],inside[2]);
151 }
152 fValue = new Value(nam,silent);
153 fKey = new Value(inside[1],silent);
154 fVal = new Value(inside[2],silent);
155 if ( !(*fValue).IsValid() || !fKey->IsValid() || !fVal->IsValid() ) {
156 return 0;
157 }
158 fPointers |= 0 != (fKey->fCase&kIsPointer);
159 if (fPointers || (0 != (fKey->fProperties&kNeedDelete))) {
161 }
162 if ( 0 == fValOffset ) {
163 fValOffset = alignedSize(fKey->fSize);
164 }
165 if ( 0 == fValDiff ) {
166 fValDiff = alignedSize(fValOffset + fVal->fSize);
167 }
168 if (num > 3 && !inside[3].empty()) {
169 if (! TClassEdit::IsDefAlloc(inside[3].c_str(),inside[0].c_str())) {
171 }
172 }
173 break;
174 case ROOT::kSTLbitset:
175 inside[1] = "bool";
176 // Intentional fall through
177 default:
178 fValue = new Value(inside[1],silent);
179 fVal = new Value(*fValue);
180 if ( !(*fValue).IsValid() || !fVal->IsValid() ) {
181 return 0;
182 }
183 if ( 0 == fValDiff ) {
185 // No need to align, the size even for a class should already
186 // be correctly padded for use in a vector.
187 }
188 if (num > 2 && !inside[2].empty()) {
189 if (! TClassEdit::IsDefAlloc(inside[2].c_str(),inside[0].c_str())) {
191 }
192 }
193 break;
194 }
195 fPointers |= 0 != (fVal->fCase&kIsPointer);
196 if (fPointers || (0 != (fVal->fProperties&kNeedDelete))) {
198 }
199 fClass = cl;
200 return this;
201 }
202 Fatal("TEmulatedCollectionProxy","Components of %s not analysed!",cl->GetName());
203 }
204 Fatal("TEmulatedCollectionProxy","Collection class %s not found!",fTypeinfo.name());
205 return 0;
206}
207
209{
210 // Return true if the collection proxy was well initialized.
211 return (0 != fCreateEnv.call);
212}
213
215{
216 // Return the current size of the container
217
218 if ( fEnv && fEnv->fObject ) {
219 return fEnv->fSize = PCont_t(fEnv->fObject)->size()/fValDiff;
220 }
221 Fatal("TEmulatedCollectionProxy","Size> Logic error - no proxy object set.");
222 return 0;
223}
224
226{
227 // Clear the emulated collection.
228 Resize(0, opt && *opt=='f');
229}
230
232{
233 // Shrink the container
234
235 typedef std::string String_t;
237 char* addr = ((char*)fEnv->fStart) + fValDiff*left;
238 size_t i;
239
240 switch ( fSTL_type ) {
241 case ROOT::kSTLmap:
243 addr = ((char*)fEnv->fStart) + fValDiff*left;
244 switch(fKey->fCase) {
245 case kIsFundamental: // Only handle primitives this way
246 case kIsEnum:
247 break;
248 case kIsClass:
249 for( i= fKey->fType ? left : nCurr; i<nCurr; ++i, addr += fValDiff ) {
250 // Call emulation in case non-compiled content
251 fKey->fType->Destructor(addr, kTRUE);
252 }
253 break;
254 case kBIT_ISSTRING:
255 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
256 ((std::string*)addr)->~String_t();
257 }
258 break;
259 case kIsPointer|kIsClass:
260 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
261 StreamHelper* h = (StreamHelper*)addr;
262 //Eventually we'll need to delete this
263 //(but only when needed).
264 void* ptr = h->ptr();
265 if (force) fKey->fType->Destructor(ptr);
266 h->set(0);
267 }
268 break;
270 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
271 StreamHelper* h = (StreamHelper*)addr;
272 //Eventually we'll need to delete this
273 //(but only when needed).
274 if (force) delete (std::string*)h->ptr();
275 h->set(0);
276 }
277 break;
279 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
280 StreamHelper* h = (StreamHelper*)addr;
281 if (force) delete (TString*)h->ptr();
282 h->set(0);
283 }
284 break;
285 }
286 addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*left;
287 // DO NOT break; just continue
288
289 // General case for all values
290 default:
291 switch( fVal->fCase ) {
292 case kIsFundamental: // Only handle primitives this way
293 case kIsEnum:
294 break;
295 case kIsClass:
296 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
297 // Call emulation in case non-compiled content
298 fVal->fType->Destructor(addr,kTRUE);
299 }
300 break;
301 case kBIT_ISSTRING:
302 for( i=left; i<nCurr; ++i, addr += fValDiff )
303 ((std::string*)addr)->~String_t();
304 break;
305 case kIsPointer|kIsClass:
306 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
307 StreamHelper* h = (StreamHelper*)addr;
308 void* p = h->ptr();
309 if ( p && force ) {
310 fVal->fType->Destructor(p);
311 }
312 h->set(0);
313 }
314 break;
316 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
317 StreamHelper* h = (StreamHelper*)addr;
318 if (force) delete (std::string*)h->ptr();
319 h->set(0);
320 }
321 break;
323 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
324 StreamHelper* h = (StreamHelper*)addr;
325 if (force) delete (TString*)h->ptr();
326 h->set(0);
327 }
328 break;
329 }
330 }
331 c->resize(left*fValDiff,0);
332 fEnv->fStart = left>0 ? &(*c->begin()) : 0;
333 return;
334}
335
337{
338 // Expand the container
339 size_t i;
341 c->resize(left*fValDiff,0);
342 void *oldstart = fEnv->fStart;
343 fEnv->fStart = left>0 ? &(*c->begin()) : 0;
344
345 char* addr = ((char*)fEnv->fStart) + fValDiff*nCurr;
346 switch ( fSTL_type ) {
347 case ROOT::kSTLmap:
349 switch(fKey->fCase) {
350 case kIsFundamental: // Only handle primitives this way
351 case kIsEnum:
352 break;
353 case kIsClass:
354 if (oldstart && oldstart != fEnv->fStart) {
355 Long_t offset = 0;
356 for( i=0; i<=nCurr; ++i, offset += fValDiff ) {
357 // For now 'Move' only register the change of location
358 // so per se this is wrong since the object are copied via memcpy
359 // rather than a copy (or move) constructor.
360 fKey->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
361 }
362 }
363 for( i=nCurr; i<left; ++i, addr += fValDiff )
364 fKey->fType->New(addr);
365 break;
366 case kBIT_ISSTRING:
367 for( i=nCurr; i<left; ++i, addr += fValDiff )
368 ::new(addr) std::string();
369 break;
370 case kIsPointer|kIsClass:
373 for( i=nCurr; i<left; ++i, addr += fValDiff )
374 *(void**)addr = 0;
375 break;
376 }
377 addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*nCurr;
378 // DO NOT break; just continue
379
380 // General case for all values
381 default:
382 switch(fVal->fCase) {
383 case kIsFundamental: // Only handle primitives this way
384 case kIsEnum:
385 break;
386 case kIsClass:
387 if (oldstart && oldstart != fEnv->fStart) {
388 Long_t offset = 0;
389 for( i=0; i<=nCurr; ++i, offset += fValDiff ) {
390 // For now 'Move' only register the change of location
391 // so per se this is wrong since the object are copied via memcpy
392 // rather than a copy (or move) constructor.
393 fVal->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
394 }
395 }
396 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
397 fVal->fType->New(addr);
398 }
399 break;
400 case kBIT_ISSTRING:
401 for( i=nCurr; i<left; ++i, addr += fValDiff )
402 ::new(addr) std::string();
403 break;
404 case kIsPointer|kIsClass:
407 for( i=nCurr; i<left; ++i, addr += fValDiff )
408 *(void**)addr = 0;
409 break;
410 }
411 break;
412 }
413}
414
416{
417 // Resize the container
418
419 if ( fEnv && fEnv->fObject ) {
420 size_t nCurr = Size();
422 fEnv->fStart = nCurr>0 ? &(*c->begin()) : 0;
423 if ( left == nCurr ) {
424 return;
425 }
426 else if ( left < nCurr ) {
427 Shrink(nCurr, left, force);
428 return;
429 }
430 Expand(nCurr, left);
431 return;
432 }
433 Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set.");
434}
435
437{
438 // Return the address of the value at index 'idx'
439 if ( fEnv && fEnv->fObject ) {
441 size_t s = c->size();
442 if ( idx >= (s/fValDiff) ) {
443 return 0;
444 }
445 return idx<(s/fValDiff) ? ((char*)&(*c->begin()))+idx*fValDiff : 0;
446 }
447 Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set.");
448 return 0;
449}
450
452{
453 // Allocate the necessary space.
454
455 Resize(n, forceDelete);
456 return fEnv->fObject;
457}
458
459////////////////////////////////////////////////////////////////////////////////
460/// Insert data into the container where data is a C-style array of the actual type contained in the collection
461/// of the given size. For associative container (map, etc.), the data type is the pair<key,value>.
462
463void TEmulatedCollectionProxy::Insert(const void * /* data */, void * /*container*/, size_t /*size*/)
464{
465 Fatal("Insert","Not yet implemented, require copy of objects.");
466}
467
469{
470}
471
473{
474 // Object input streamer
475 Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
476 StreamHelper* itm = (StreamHelper*)At(0);
477 switch (fVal->fCase) {
478 case kIsFundamental: // Only handle primitives this way
479 case kIsEnum:
480 switch( int(fVal->fKind) ) {
481 case kBool_t: b.ReadFastArray(&itm->boolean , nElements); break;
482 case kChar_t: b.ReadFastArray(&itm->s_char , nElements); break;
483 case kShort_t: b.ReadFastArray(&itm->s_short , nElements); break;
484 case kInt_t: b.ReadFastArray(&itm->s_int , nElements); break;
485 case kLong_t: b.ReadFastArray(&itm->s_long , nElements); break;
486 case kLong64_t: b.ReadFastArray(&itm->s_longlong, nElements); break;
487 case kFloat_t: b.ReadFastArray(&itm->flt , nElements); break;
488 case kFloat16_t: b.ReadFastArrayFloat16(&itm->flt, nElements); break;
489 case kDouble_t: b.ReadFastArray(&itm->dbl , nElements); break;
490 case kUChar_t: b.ReadFastArray(&itm->u_char , nElements); break;
491 case kUShort_t: b.ReadFastArray(&itm->u_short , nElements); break;
492 case kUInt_t: b.ReadFastArray(&itm->u_int , nElements); break;
493 case kULong_t: b.ReadFastArray(&itm->u_long , nElements); break;
494 case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
495 case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
496 case kchar:
497 case kNoType_t:
498 case kOther_t:
499 Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
500 }
501 break;
502
503#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
504
505 case kIsClass:
506 DOLOOP( b.StreamObject(i,fVal->fType) );
507 case kBIT_ISSTRING:
508 DOLOOP( i->read_std_string(b) );
509 case kIsPointer|kIsClass:
510 DOLOOP( i->read_any_object(fVal,b) );
512 DOLOOP( i->read_std_string_pointer(b) );
514 DOLOOP( i->read_tstring_pointer(vsn3,b) );
515 }
516
517#undef DOLOOP
518
519}
520
522{
523 // Object output streamer
524 StreamHelper* itm = (StreamHelper*)At(0);
525 switch (fVal->fCase) {
526 case kIsFundamental: // Only handle primitives this way
527 case kIsEnum:
528 itm = (StreamHelper*)At(0);
529 switch( int(fVal->fKind) ) {
530 case kBool_t: b.WriteFastArray(&itm->boolean , nElements); break;
531 case kChar_t: b.WriteFastArray(&itm->s_char , nElements); break;
532 case kShort_t: b.WriteFastArray(&itm->s_short , nElements); break;
533 case kInt_t: b.WriteFastArray(&itm->s_int , nElements); break;
534 case kLong_t: b.WriteFastArray(&itm->s_long , nElements); break;
535 case kLong64_t: b.WriteFastArray(&itm->s_longlong, nElements); break;
536 case kFloat_t: b.WriteFastArray(&itm->flt , nElements); break;
537 case kFloat16_t: b.WriteFastArrayFloat16(&itm->flt, nElements); break;
538 case kDouble_t: b.WriteFastArray(&itm->dbl , nElements); break;
539 case kUChar_t: b.WriteFastArray(&itm->u_char , nElements); break;
540 case kUShort_t: b.WriteFastArray(&itm->u_short , nElements); break;
541 case kUInt_t: b.WriteFastArray(&itm->u_int , nElements); break;
542 case kULong_t: b.WriteFastArray(&itm->u_long , nElements); break;
543 case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
544 case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
545 case kchar:
546 case kNoType_t:
547 case kOther_t:
548 Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
549 }
550 break;
551#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
552 case kIsClass:
553 DOLOOP( b.StreamObject(i,fVal->fType) );
554 case kBIT_ISSTRING:
555 DOLOOP( TString(i->c_str()).Streamer(b) );
556 case kIsPointer|kIsClass:
557 DOLOOP( b.WriteObjectAny(i->ptr(),fVal->fType) );
559 DOLOOP( i->write_std_string_pointer(b) );
561 DOLOOP( i->write_tstring_pointer(b) );
562 }
563#undef DOLOOP
564}
565
566void TEmulatedCollectionProxy::ReadBuffer(TBuffer &b, void *obj, const TClass *onfileClass)
567{
568 // Read portion of the streamer.
569
570 SetOnFileClass((TClass*)onfileClass);
571 ReadBuffer(b,obj);
572}
573
575{
576 // Read portion of the streamer.
577
578 TPushPop env(this,obj);
579 int nElements = 0;
580 b >> nElements;
581 if ( fEnv->fObject ) {
582 Resize(nElements,true);
583 }
584 if ( nElements > 0 ) {
585 ReadItems(nElements, b);
586 }
587}
588
590{
591 // TClassStreamer IO overload
592 if ( b.IsReading() ) { //Read mode
593 int nElements = 0;
594 b >> nElements;
595 if ( fEnv->fObject ) {
596 Resize(nElements,true);
597 }
598 if ( nElements > 0 ) {
599 ReadItems(nElements, b);
600 }
601 }
602 else { // Write case
603 int nElements = fEnv->fObject ? Size() : 0;
604 b << nElements;
605 if ( nElements > 0 ) {
606 WriteItems(nElements, b);
607 }
608 }
609}
610
611//
612// Utility functions
613//
614static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset)
615{
616 // Create a TStreamerElement for the type 'dmFull' and whose data member name is 'dmName'.
617
618 TString s1( TClassEdit::ShortType(dmFull,0) );
619 TString dmType( TClassEdit::ShortType(dmFull,1) );
620 Bool_t dmIsPtr = (s1 != dmType);
621 const char *dmTitle = "Emulation";
622
623 TDataType *dt = gROOT->GetType(dmType);
624 if (dt && dt->GetType() > 0 ) { // found a basic type
625 Int_t dsize,dtype;
626 dtype = dt->GetType();
627 dsize = dt->Size();
628 if (dmIsPtr && dtype != kCharStar) {
629 Error("Pair Emulation Building","%s is not yet supported in pair emulation",
630 dmFull);
631 return 0;
632 } else {
633 TStreamerElement *el = new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull);
634 el->SetSize(dsize);
635 return el;
636 }
637 } else {
638
639 static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
640 if (strcmp(dmType,"string") == 0 || strcmp(dmType,"std::string") == 0 || strcmp(dmType,full_string_name)==0 ) {
641 return new TStreamerSTLstring(dmName,dmTitle,offset,dmFull,dmIsPtr);
642 }
643 if (TClassEdit::IsSTLCont(dmType)) {
644 return new TStreamerSTL(dmName,dmTitle,offset,dmFull,dmFull,dmIsPtr);
645 }
646 TClass *clm = TClass::GetClass(dmType);
647 if (!clm) {
648 // either we have an Emulated enum or a really unknown class!
649 // let's just claim its an enum :(
650 Int_t dtype = kInt_t;
651 return new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull);
652 }
653 // a pointer to a class
654 if ( dmIsPtr ) {
655 if (clm->IsTObject()) {
656 return new TStreamerObjectPointer(dmName,dmTitle,offset,dmFull);
657 } else {
658 return new TStreamerObjectAnyPointer(dmName,dmTitle,offset,dmFull);
659 }
660 }
661 // a class
662 if (clm->IsTObject()) {
663 return new TStreamerObject(dmName,dmTitle,offset,dmFull);
664 } else if(clm == TString::Class() && !dmIsPtr) {
665 return new TStreamerString(dmName,dmTitle,offset);
666 } else {
667 return new TStreamerObjectAny(dmName,dmTitle,offset,dmFull);
668 }
669 }
670}
671
672
673static TStreamerInfo *R__GenerateTClassForPair(const std::string &fname, const std::string &sname)
674{
675 // Generate a TStreamerInfo for a std::pair<fname,sname>
676 // This TStreamerInfo is then used as if it was read from a file to generate
677 // and emulated TClass.
678
679 TStreamerInfo *i = (TStreamerInfo*)TClass::GetClass("pair<const int,int>")->GetStreamerInfo()->Clone();
680 std::string pname = "pair<"+fname+","+sname;
681 pname += (pname[pname.length()-1]=='>') ? " >" : ">";
682 i->SetName(pname.c_str());
683 i->SetClass(0);
684 i->GetElements()->Delete();
685 TStreamerElement *fel = R__CreateEmulatedElement("first", fname.c_str(), 0);
686 Int_t size = 0;
687 if (fel) {
688 i->GetElements()->Add( fel );
689
690 size = fel->GetSize();
691 Int_t sp = sizeof(void *);
692 //align the non-basic data types (required on alpha and IRIX!!)
693 if (size%sp != 0) size = size - size%sp + sp;
694 } else {
695 delete i;
696 return 0;
697 }
698 TStreamerElement *second = R__CreateEmulatedElement("second", sname.c_str(), size);
699 if (second) {
700 i->GetElements()->Add( second );
701 } else {
702 delete i;
703 return 0;
704 }
705 Int_t oldlevel = gErrorIgnoreLevel;
706 // Hide the warning about the missing pair dictionary.
708 i->BuildCheck();
709 gErrorIgnoreLevel = oldlevel;
710 i->BuildOld();
711 return i;
712}
void Class()
Definition: Class.C:29
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define s1(x)
Definition: RSha256.hxx:91
#define h(i)
Definition: RSha256.hxx:106
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
@ kNoType_t
Definition: TDataType.h:33
@ kFloat_t
Definition: TDataType.h:31
@ kULong64_t
Definition: TDataType.h:32
@ kInt_t
Definition: TDataType.h:30
@ kchar
Definition: TDataType.h:31
@ kLong_t
Definition: TDataType.h:30
@ kDouble32_t
Definition: TDataType.h:31
@ kShort_t
Definition: TDataType.h:29
@ kBool_t
Definition: TDataType.h:32
@ kULong_t
Definition: TDataType.h:30
@ kLong64_t
Definition: TDataType.h:32
@ kUShort_t
Definition: TDataType.h:29
@ kDouble_t
Definition: TDataType.h:31
@ kCharStar
Definition: TDataType.h:34
@ kChar_t
Definition: TDataType.h:29
@ kUChar_t
Definition: TDataType.h:29
@ kUInt_t
Definition: TDataType.h:30
@ kFloat16_t
Definition: TDataType.h:33
@ kOther_t
Definition: TDataType.h:32
@ kIsPointer
Definition: TDictionary.h:77
@ kIsClass
Definition: TDictionary.h:65
@ kIsEnum
Definition: TDictionary.h:68
@ kIsFundamental
Definition: TDictionary.h:70
#define DOLOOP(x)
static TStreamerElement * R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset)
static TStreamerInfo * R__GenerateTClassForPair(const std::string &f, const std::string &s)
const Int_t kError
Definition: TError.h:39
void Error(const char *location, const char *msgfmt,...)
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
void Warning(const char *location, const char *msgfmt,...)
void Fatal(const char *location, const char *msgfmt,...)
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
#define gROOT
Definition: TROOT.h:410
#define R__LOCKGUARD(mutex)
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition: TClass.cxx:4452
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4824
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:5181
void Move(void *arenaFrom, void *arenaTo) const
Register the fact that an object was moved from the memory location 'arenaFrom' to the memory locatio...
Definition: TClass.cxx:4180
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5700
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
Int_t Size() const
Get size of basic typedef'ed type.
Definition: TDataType.cxx:366
Streamer around an arbitrary STL like container, which implements basic container functionality.
virtual TGenCollectionProxy * InitializeEx(Bool_t silent)
Proxy initializer.
virtual void Insert(const void *data, void *container, size_t size)
Insert data into the container where data is a C-style array of the actual type contained in the coll...
virtual void DeleteArray(void *p, Bool_t dtorOnly=kFALSE) const
virtual void Streamer(TBuffer &refBuffer)
Streamer Function.
void Expand(UInt_t nCurr, UInt_t left)
virtual void Destructor(void *p, Bool_t dtorOnly=kFALSE) const
void WriteItems(int nElements, TBuffer &b)
virtual void ReadBuffer(TBuffer &buff, void *pObj)
virtual void Commit(void *env)
Commit the change.
virtual void Resize(UInt_t n, Bool_t force_delete)
Resize the container.
void Shrink(UInt_t nCurr, UInt_t left, Bool_t force)
virtual void Clear(const char *opt="")
Clear the emulated collection.
virtual TVirtualCollectionProxy * Generate() const
Virtual copy constructor.
virtual void * Allocate(UInt_t n, Bool_t forceDelete)
Allocate the needed space.
virtual UInt_t Size() const
Return the current size of the container.
void ReadItems(int nElements, TBuffer &b)
TEmulatedCollectionProxy(const TEmulatedCollectionProxy &copy)
virtual void * At(UInt_t idx)
Return the address of the value at index 'idx'.
Proxy around an arbitrary container, which implements basic functionality and iteration.
std::atomic< Value * > fValue
Descriptor of the container value type.
Bool_t fPointers
Flag to indicate if containee has pointers (key or value)
Info_t fTypeinfo
Type information.
int fValOffset
Offset from key to value (in maps)
EnvironBase_t * fEnv
Address of the currently proxied object.
TGenCollectionProxy * Initialize(Bool_t silent) const
Proxy initializer.
std::string fName
Name of the class being proxied.
int fSTL_type
STL container type.
Value * fKey
Descriptor of the key_type.
Method0 fCreateEnv
Method to allocate an Environment holder.
Value * fVal
Descriptor of the Value_type.
virtual void SetOnFileClass(TClass *cl)
int fValDiff
Offset between two consecutive value_types (memory layout).
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
void Add(TObject *obj)
Definition: TObjArray.h:73
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:355
virtual void SetSize(Int_t dsize)
virtual Int_t GetSize() const
Returns size of this element in bytes.
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
TObjArray * GetElements() const
void BuildCheck(TFile *file=0)
Check if built and consistent with the class dictionary.
void BuildOld()
rebuild the TStreamerInfo structure
void SetClass(TClass *cl)
Basic string class.
Definition: TString.h:131
const Int_t n
Definition: legend1.C:16
@ kSTLbitset
Definition: ESTLType.h:37
@ kSTLmap
Definition: ESTLType.h:33
@ kSTLmultimap
Definition: ESTLType.h:34
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
Definition: TClassEdit.cxx:478
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
Definition: TClassEdit.cxx:948
bool IsDefAlloc(const char *alloc, const char *classname)
return whether or not 'allocname' is the STL default allocator for type 'classname'
Definition: TClassEdit.cxx:567
static constexpr double second
static constexpr double s
STL namespace.
const char * Value
Definition: TXMLSetup.cxx:72
UInt_t fCase
type of data of Value_type
TClassRef fType
TClass reference of Value_type in collection.
UInt_t fProperties
Additional properties of the value type (kNeedDelete)
size_t fSize
fSize of the contained object
EDataType fKind
kind of ROOT-fundamental type
Bool_t IsValid()
Return true if the Value has been properly initialized.
Helper class to facilitate I/O.