Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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_other
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 "TClass.h"
28#include "TStreamerElement.h"
29#include "TStreamerInfo.h"
30#include "TClassEdit.h"
31#include "TError.h"
32#include "TEnum.h"
33#include "TROOT.h"
34#include <iostream>
35
36#include "TVirtualMutex.h" // For R__LOCKGUARD
37#include "TInterpreter.h" // For gInterpreterMutex
38
39//
40// Utility function to allow the creation of a TClass for a std::pair without
41// a dictionary (See end of file for implementation
42//
43
46{
47 // Build a Streamer for an emulated vector whose type is 'name'.
49}
50
53{
54 // Build a Streamer for a collection whose type is described by 'collectionClass'.
55
56 fName = cl_name;
57 if ( this->TEmulatedCollectionProxy::InitializeEx(silent) ) {
59 }
61}
62
64{
65 // Standard destructor
66 if ( fEnv && fEnv->fObject ) {
67 Clear();
68 }
69}
70
72{
73 // Virtual copy constructor
74
75 if ( !fClass ) Initialize(kFALSE);
76 return new TEmulatedCollectionProxy(*this);
77}
78
80{
81 // Virtual destructor
82
83 if (!p) return;
84 if (!fEnv || fEnv->fObject != p) { // Envoid the cost of TPushPop if we don't need it
85 // FIXME: This is not thread safe.
87 const_cast<TEmulatedCollectionProxy*>(this)->Clear("force");
88 } else {
89 const_cast<TEmulatedCollectionProxy*>(this)->Clear("force");
90 }
91 if (dtorOnly) {
92 WithCont(p, [](auto *c, std::size_t) {
93 using Vec_t = std::decay_t<decltype(*c)>;
94 c->~Vec_t();
95 });
96 } else {
97 WithCont(p, [](auto *c, std::size_t) { delete c; });
98 }
99}
100
102{
103 // Virtual array destructor
104
105 // Cannot implement this properly, we do not know
106 // how many elements are in the array.
107 Warning("DeleteArray", "Cannot properly delete emulated array of %s at %p, I don't know how many elements it has!", fClass->GetName(), p);
108 if (!dtorOnly) {
109 ::operator delete(p);
110 }
111}
112
114{
115 // Proxy initializer
117 if (fClass) return this;
118
119
120 TClass *cl = TClass::GetClass(fName.c_str(), kTRUE, silent);
121 fEnv = 0;
122 fKey = 0;
123 if ( cl ) {
124 int nested = 0;
125 std::vector<std::string> inside;
126 fPointers = false;
127 int num = TClassEdit::GetSplit(fName.c_str(),inside,nested);
128 if ( num > 1 ) {
129 std::string nam;
130 if ( inside[0].find("stdext::hash_") != std::string::npos ) {
131 inside[0].replace(3,10,"::");
132 }
133 if ( inside[0].find("__gnu_cxx::hash_") != std::string::npos ) {
134 inside[0].replace(0,16,"std::");
135 }
136 fSTL_type = TClassEdit::STLKind(inside[0]);
137 // Note: an emulated collection proxy is never really associative
138 // since under-neath is actually an array.
139
140 auto alignedSize = [](size_t in, TClass *align_cl) {
141 size_t align = align_cl ? align_cl->GetClassAlignment() : alignof(std::max_align_t);
142 return in + (align - in % align) % align;
143 };
145 TEnum *fTemporaryTEnum = nullptr;
146
148 {
149 if (typecase == kIsEnum && !TEnum::GetEnum(enumname.c_str())) {
150 fTemporaryTEnum = new TEnum();
151 fTemporaryTEnum->SetName(enumname.c_str());
152 gROOT->GetListOfEnums()->Add(fTemporaryTEnum);
153 }
154 }
155
157 {
158 if (fTemporaryTEnum) {
159 gROOT->GetListOfEnums()->Remove(fTemporaryTEnum);
160 delete fTemporaryTEnum;
161 }
162 }
163 };
164 switch ( fSTL_type ) {
165 case ROOT::kSTLmap:
167 nam = "pair<"+inside[1]+","+inside[2];
168 nam += (nam[nam.length()-1]=='>') ? " >" : ">";
169 fKey = new Value(inside[1],silent);
170 fVal = new Value(inside[2],silent);
171 {
172 // We have the case of an on-file enum or an unknown class, since
173 // this comes from a file, we also know that the type was valid but
174 // since we have no information it was either
175 // a. an enum
176 // b. a class of type that was never stored
177 // c. a class with a custom streamer
178 // We can "safely" pretend that it is an enum in all 3 case because
179 // a. obviously
180 // b. it will not be used anyway (no object of that type on the file)
181 // c. since we don't know the class we don't have the Streamer and thus can read it anyway
182 // So let's temporarily pretend it is an enum.
185
186 if (0==TClass::GetClass(nam.c_str(), kTRUE, silent)) {
187 // We need to emulate the pair
188 TVirtualStreamerInfo::Factory()->GenerateInfoForPair(inside[1],inside[2], silent, 0, 0);
189 }
190 }
191 fValue = new Value(nam,silent);
192 if ( !(*fValue).IsValid() || !fKey->IsValid() || !fVal->IsValid() ) {
193 return 0;
194 }
195 fPointers |= 0 != (fKey->fCase&kIsPointer);
196 if (fPointers || (0 != (fKey->fProperties&kNeedDelete))) {
198 }
199 if ( 0 == fValOffset ) {
200 fValOffset = alignedSize(fKey->fSize, (*fValue).fType.GetClass());
201 }
202 if ( 0 == fValDiff ) {
203 fValDiff = alignedSize(fValOffset + fVal->fSize, (*fValue).fType.GetClass());
204 }
205 if (num > 3 && !inside[3].empty()) {
206 if (! TClassEdit::IsDefAlloc(inside[3].c_str(),inside[0].c_str())) {
208 }
209 }
210 break;
211 case ROOT::kSTLbitset:
212 inside[1] = "bool";
213 // Intentional fall through
214 default:
215 fValue = new Value(inside[1],silent);
216 fVal = new Value(*fValue);
217 if ( !(*fValue).IsValid() || !fVal->IsValid() ) {
218 return 0;
219 }
220 if ( 0 == fValDiff ) {
222 // No need to align, the size even for a class should already
223 // be correctly padded for use in a vector.
224 }
225 if (num > 2 && !inside[2].empty()) {
226 if (! TClassEdit::IsDefAlloc(inside[2].c_str(),inside[0].c_str())) {
228 }
229 }
230 break;
231 }
232 fPointers |= 0 != (fVal->fCase&kIsPointer);
233 if (fPointers || (0 != (fVal->fProperties&kNeedDelete))) {
235 }
236 fClass = cl;
237 return this;
238 }
239 Fatal("TEmulatedCollectionProxy","Components of %s not analysed!",cl->GetName());
240 }
241 Fatal("TEmulatedCollectionProxy","Collection class %s not found!",fTypeinfo.name());
242 return 0;
243}
244
246{
247 // Return true if the collection proxy was well initialized.
248 return (0 != fCreateEnv.call);
249}
250
252{
253 // Return the current size of the container
254
255 if ( fEnv && fEnv->fObject ) {
256 return fEnv->fSize = PCont_t(fEnv->fObject)->size()/fValDiff;
257 }
258 Fatal("TEmulatedCollectionProxy","Size> Logic error - no proxy object set.");
259 return 0;
260}
261
263{
264 // Clear the emulated collection.
265 Resize(0, opt && *opt=='f');
266}
267
269{
270 // Shrink the container
271
272 typedef std::string String_t;
273 char *addr = ((char *)fEnv->fStart) + ElementOffset(left);
274 size_t i;
275
276 switch ( fSTL_type ) {
277 case ROOT::kSTLmap:
279 addr = ((char *)fEnv->fStart) + ElementOffset(left);
280 switch(fKey->fCase) {
281 case kIsFundamental: // Only handle primitives this way
282 case kIsEnum:
283 break;
284 case kIsClass:
285 for( i= fKey->fType ? left : nCurr; i<nCurr; ++i, addr += fValDiff ) {
286 // Call emulation in case non-compiled content
288 }
289 break;
290 case kBIT_ISSTRING:
291 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
292 ((std::string*)addr)->~String_t();
293 }
294 break;
295 case kIsPointer|kIsClass:
296 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
298 //Eventually we'll need to delete this
299 //(but only when needed).
300 void* ptr = h->ptr();
301 if (force) fKey->fType->Destructor(ptr);
302 h->set(0);
303 }
304 break;
306 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
308 //Eventually we'll need to delete this
309 //(but only when needed).
310 if (force) delete (std::string*)h->ptr();
311 h->set(0);
312 }
313 break;
315 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
317 if (force) delete (TString*)h->ptr();
318 h->set(0);
319 }
320 break;
321 }
322 addr = ((char *)fEnv->fStart) + fValOffset + ElementOffset(left);
323 // DO NOT break; just continue
324
325 // General case for all values
326 default:
327 switch( fVal->fCase ) {
328 case kIsFundamental: // Only handle primitives this way
329 case kIsEnum:
330 break;
331 case kIsClass:
332 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
333 // Call emulation in case non-compiled content
335 }
336 break;
337 case kBIT_ISSTRING:
338 for( i=left; i<nCurr; ++i, addr += fValDiff )
339 ((std::string*)addr)->~String_t();
340 break;
341 case kIsPointer|kIsClass:
342 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
344 void* p = h->ptr();
345 if ( p && force ) {
347 }
348 h->set(0);
349 }
350 break;
352 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
354 if (force) delete (std::string*)h->ptr();
355 h->set(0);
356 }
357 break;
359 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
361 if (force) delete (TString*)h->ptr();
362 h->set(0);
363 }
364 break;
365 }
366 }
367 WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) {
368 assert(fValDiff % alignmentElemSize == 0);
369 c->resize(ElementOffset(left) / alignmentElemSize);
370 fEnv->fStart = left > 0 ? c->data() : nullptr;
371 });
372 return;
373}
374
376{
377 // Expand the container
378 size_t i;
379
380 // The storage is a std::vector of raw, aligned bytes: growing it past its
381 // capacity relocates the elements with a raw memory copy. That corrupts an
382 // object holding a pointer into itself -- notably std::string (and TString)
383 // using the small-string optimization, whose data pointer would keep pointing
384 // into the old, freed, buffer and be freed again from there when the object is
385 // destroyed (https://github.com/root-project/root/issues/20882).
386 //
387 // TClass::Move (used below) does not actually move the data (in the C++ sense), so it cannot fix
388 // those up. Expand is however only reached while preparing the collection to
389 // be entirely overwritten by a member-wise read, so we destroy such elements
390 // here -- while they are still valid -- and let the code below reconstruct
391 // them at the new location instead of relocating them.
392 auto needsRealMove = [](const Value *v) {
393 if (!v || (v->fCase & kIsPointer))
394 return false; // a pointer relocates fine
395 if (v->fCase & kBIT_ISSTRING)
396 return true; // std::string, see above
397 if (v->fCase & kIsClass) {
398 // TClass is conservative for the types the interpreter does not know.
399 TClass *cl = v->fType.GetClass();
400 return !cl || !cl->IsTriviallyRelocatable();
401 }
402 return false; // fundamental types and enums
403 };
404 if (nCurr > 0) {
405 // Only worth asking about the type if the buffer actually reallocates.
406 bool willReallocate = false;
407 WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) {
408 willReallocate = (ElementOffset(left) / alignmentElemSize) > c->capacity();
409 });
411 // Destroys the elements in place and resizes to 0, keeping the capacity;
412 // the buffer grows again right below with no live object to relocate.
413 // 'force' is the caller's: it decides whether pointees are deleted too.
414 Shrink(nCurr, 0, force);
415 nCurr = 0;
416 }
417 }
418
419 void *oldstart = fEnv->fStart;
420 WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) {
421 assert(fValDiff % alignmentElemSize == 0);
422 c->resize(ElementOffset(left) / alignmentElemSize);
423 fEnv->fStart = left > 0 ? c->data() : nullptr;
424 });
425
426 char *addr = ((char *)fEnv->fStart) + ElementOffset(nCurr);
427 switch ( fSTL_type ) {
428 case ROOT::kSTLmap:
430 switch(fKey->fCase) {
431 case kIsFundamental: // Only handle primitives this way
432 case kIsEnum:
433 break;
434 case kIsClass:
435 if (oldstart && oldstart != fEnv->fStart) {
436 Long_t offset = 0;
437 for (i = 0; i < nCurr; ++i, offset += fValDiff) {
438 // For now 'Move' only register the change of location
439 // so per se this is wrong since the object are copied via memcpy
440 // rather than a copy (or move) constructor.
441 fKey->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
442 }
443 }
444 for( i=nCurr; i<left; ++i, addr += fValDiff )
445 fKey->fType->New(addr);
446 break;
447 case kBIT_ISSTRING:
448 for( i=nCurr; i<left; ++i, addr += fValDiff )
449 ::new(addr) std::string();
450 break;
451 case kIsPointer|kIsClass:
454 for( i=nCurr; i<left; ++i, addr += fValDiff )
455 *(void**)addr = 0;
456 break;
457 }
458 addr = ((char *)fEnv->fStart) + fValOffset + ElementOffset(nCurr);
459 // DO NOT break; just continue
460
461 // General case for all values
462 default:
463 switch(fVal->fCase) {
464 case kIsFundamental: // Only handle primitives this way
465 case kIsEnum:
466 break;
467 case kIsClass:
468 if (oldstart && oldstart != fEnv->fStart) {
469 // fValOffset locates the value inside the element, as it does
470 // for the New() loop below; for a map it is past the key.
472 for (i = 0; i < nCurr; ++i, offset += fValDiff) {
473 // For now 'Move' only register the change of location
474 // so per se this is wrong since the object are copied via memcpy
475 // rather than a copy (or move) constructor.
476 fVal->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
477 }
478 }
479 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
480 fVal->fType->New(addr);
481 }
482 break;
483 case kBIT_ISSTRING:
484 for( i=nCurr; i<left; ++i, addr += fValDiff )
485 ::new(addr) std::string();
486 break;
487 case kIsPointer|kIsClass:
490 for( i=nCurr; i<left; ++i, addr += fValDiff )
491 *(void**)addr = 0;
492 break;
493 }
494 break;
495 }
496}
497
499{
500 // Resize the container
501
502 if ( fEnv && fEnv->fObject ) {
503 size_t nCurr = Size();
505 fEnv->fStart = nCurr > 0 ? c->data() : 0;
506 if ( left == nCurr ) {
507 return;
508 }
509 else if ( left < nCurr ) {
510 Shrink(nCurr, left, force);
511 return;
512 }
513 Expand(nCurr, left, force);
514 return;
515 }
516 Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set.");
517}
518
520{
521 // Return the address of the value at index 'idx'
522 if ( fEnv && fEnv->fObject ) {
524 size_t s = c->size();
525 if ( idx >= (s/fValDiff) ) {
526 return 0;
527 }
528 return idx < (s / fValDiff) ? c->data() + ElementOffset(idx) : 0;
529 }
530 Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set.");
531 return 0;
532}
533
535{
536 // Allocate the necessary space.
537
539 return fEnv->fObject;
540}
541
542////////////////////////////////////////////////////////////////////////////////
543/// Insert data into the container where data is a C-style array of the actual type contained in the collection
544/// of the given size. For associative container (map, etc.), the data type is the pair<key,value>.
545
546void TEmulatedCollectionProxy::Insert(const void * /* data */, void * /*container*/, size_t /*size*/)
547{
548 Fatal("Insert","Not yet implemented, require copy of objects.");
549}
550
552{
553}
554
556{
557 // Object input streamer
558 Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
560 switch (fVal->fCase) {
561 case kIsFundamental: // Only handle primitives this way
562 case kIsEnum:
563 switch( int(fVal->fKind) ) {
564 case kBool_t: b.ReadFastArray(&itm->boolean , nElements); break;
565 case kChar_t: b.ReadFastArray(&itm->s_char , nElements); break;
566 case kShort_t: b.ReadFastArray(&itm->s_short , nElements); break;
567 case kInt_t: b.ReadFastArray(&itm->s_int , nElements); break;
568 case kLong_t: b.ReadFastArray(&itm->s_long , nElements); break;
569 case kLong64_t: b.ReadFastArray(&itm->s_longlong, nElements); break;
570 case kFloat_t: b.ReadFastArray(&itm->flt , nElements); break;
571 case kFloat16_t: b.ReadFastArrayFloat16(&itm->flt, nElements); break;
572 case kDouble_t: b.ReadFastArray(&itm->dbl , nElements); break;
573 case kUChar_t: b.ReadFastArray(&itm->u_char , nElements); break;
574 case kUShort_t: b.ReadFastArray(&itm->u_short , nElements); break;
575 case kUInt_t: b.ReadFastArray(&itm->u_int , nElements); break;
576 case kULong_t: b.ReadFastArray(&itm->u_long , nElements); break;
577 case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
578 case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
579 case kchar:
580 case kNoType_t:
581 case kOther_t:
582 Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
583 }
584 break;
585
586 // clang-format off
587#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + ElementOffset(idx)); { x ;} ++idx;} break;}
588 // clang-format on
589
590 case kIsClass:
591 DOLOOP( b.StreamObject(i,fVal->fType) );
592 case kBIT_ISSTRING:
593 DOLOOP( i->read_std_string(b) );
594 case kIsPointer|kIsClass:
595 DOLOOP( i->read_any_object(fVal,b) );
597 DOLOOP( i->read_std_string_pointer(b) );
599 DOLOOP( i->read_tstring_pointer(vsn3,b) );
600 }
601
602#undef DOLOOP
603
604}
605
607{
608 // Object output streamer
610 switch (fVal->fCase) {
611 case kIsFundamental: // Only handle primitives this way
612 case kIsEnum:
613 itm = (StreamHelper*)At(0);
614 switch( int(fVal->fKind) ) {
615 case kBool_t: b.WriteFastArray(&itm->boolean , nElements); break;
616 case kChar_t: b.WriteFastArray(&itm->s_char , nElements); break;
617 case kShort_t: b.WriteFastArray(&itm->s_short , nElements); break;
618 case kInt_t: b.WriteFastArray(&itm->s_int , nElements); break;
619 case kLong_t: b.WriteFastArray(&itm->s_long , nElements); break;
620 case kLong64_t: b.WriteFastArray(&itm->s_longlong, nElements); break;
621 case kFloat_t: b.WriteFastArray(&itm->flt , nElements); break;
622 case kFloat16_t: b.WriteFastArrayFloat16(&itm->flt, nElements); break;
623 case kDouble_t: b.WriteFastArray(&itm->dbl , nElements); break;
624 case kUChar_t: b.WriteFastArray(&itm->u_char , nElements); break;
625 case kUShort_t: b.WriteFastArray(&itm->u_short , nElements); break;
626 case kUInt_t: b.WriteFastArray(&itm->u_int , nElements); break;
627 case kULong_t: b.WriteFastArray(&itm->u_long , nElements); break;
628 case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
629 case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
630 case kchar:
631 case kNoType_t:
632 case kOther_t:
633 Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
634 }
635 break;
636 // clang-format off
637#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + ElementOffset(idx)); { x ;} ++idx;} break;}
638 // clang-format on
639 case kIsClass:
640 DOLOOP( b.StreamObject(i,fVal->fType) );
641 case kBIT_ISSTRING:
642 DOLOOP( TString(i->c_str()).Streamer(b) );
643 case kIsPointer|kIsClass:
644 DOLOOP( b.WriteObjectAny(i->ptr(),fVal->fType) );
646 DOLOOP( i->write_std_string_pointer(b) );
648 DOLOOP( i->write_tstring_pointer(b) );
649 }
650#undef DOLOOP
651}
652
654{
655 // Read portion of the streamer.
656
658 ReadBuffer(b,obj);
659}
660
662{
663 // Read portion of the streamer.
664
665 TPushPop env(this,obj);
666 int nElements = 0;
667 b >> nElements;
668 if ( fEnv->fObject ) {
669 Resize(nElements,true);
670 }
671 if ( nElements > 0 ) {
673 }
674}
675
677{
678 // TClassStreamer IO overload
679 if ( b.IsReading() ) { //Read mode
680 int nElements = 0;
681 b >> nElements;
682 if ( fEnv->fObject ) {
683 Resize(nElements,true);
684 }
685 if ( nElements > 0 ) {
687 }
688 }
689 else { // Write case
690 int nElements = fEnv->fObject ? Size() : 0;
691 b << nElements;
692 if ( nElements > 0 ) {
694 }
695 }
696}
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ 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
@ 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:78
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsFundamental
Definition TDictionary.h:70
#define DOLOOP(x)
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
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:267
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
R__EXTERN TVirtualMutex * gInterpreterMutex
#define gROOT
Definition TROOT.h:417
#define R__LOCKGUARD(mutex)
Buffer base class used for serializing objects.
Definition TBuffer.h:43
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5111
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition TClass.cxx:5533
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:4423
Bool_t IsTriviallyRelocatable() const
Return kTRUE if an object of this class can be relocated to a new address with a raw memory copy,...
Definition TClass.cxx:4409
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:2999
Streamer around an arbitrary STL like container, which implements basic container functionality.
UInt_t Size() const override
Return the current number of elements in the container.
void Insert(const void *data, void *container, size_t size) override
Insert data into the container where data is a C-style array of the actual type contained in the coll...
TGenCollectionProxy * InitializeEx(Bool_t silent) override
Proxy initializer.
void * Allocate(UInt_t n, Bool_t forceDelete) override
Allocates space for storing at least n elements.
void WriteItems(int nElements, TBuffer &b)
TVirtualCollectionProxy * Generate() const override
Returns a clean object of the actual class that derives from TVirtualCollectionProxy.
void Commit(void *env) override
Commits pending elements in a staging area (see Allocate() for more information).
void Expand(UInt_t nCurr, UInt_t left, Bool_t force)
void Clear(const char *opt="") override
Clear the container.
void Shrink(UInt_t nCurr, UInt_t left, Bool_t force)
void * At(UInt_t idx) override
Return the address of the value at index idx
void ReadItems(int nElements, TBuffer &b)
void WithCont(void *obj, F &&fn) const
Invoke fn(typed_ptr, elemSize) where typed_ptr is the container pointer cast to the correct AlignedSt...
void Destructor(void *p, Bool_t dtorOnly=kFALSE) const override
Execute the container destructor.
void ReadBuffer(TBuffer &buff, void *pObj) override
void Streamer(TBuffer &refBuffer) override
Streamer Function.
void DeleteArray(void *p, Bool_t dtorOnly=kFALSE) const override
Execute the container array destructor.
TEmulatedCollectionProxy(const TEmulatedCollectionProxy &copy)
void Resize(UInt_t n, Bool_t force_delete) override
Resize the container.
The TEnum class implements the enum type.
Definition TEnum.h:33
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:181
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)
std::size_t ElementOffset(std::size_t n) const
Byte offset of the n-th element.
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).
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Basic string class.
Definition TString.h:137
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1493
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
@ kCustomAlloc
The collection has a custom allocator.
@ kNeedDelete
The collection contains directly or indirectly (via other collection) some pointers that need explici...
static TVirtualStreamerInfo * Factory()
Static function returning a pointer to a new TVirtualStreamerInfo object.
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.
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.
bool IsDefAlloc(const char *alloc, const char *classname)
return whether or not 'allocname' is the STL default allocator for type 'classname'
Small helper to describe the Value_type or the key_type of an STL container.
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.