ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
16 Streamer around an arbitrary STL like container, which implements basic
17 container functionality.
18 
19 ### Note:
20 Although this class contains all the setup necessary to deal
21 with maps, the map-like functionality is NOT supported.
22 For optimization reasons this functionality is put into
23 the 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 
42 static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset);
43 static TStreamerInfo *R__GenerateTClassForPair(const std::string &f, const std::string &s);
44 
46  : TGenCollectionProxy(copy)
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 
80 void 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.
87  TVirtualCollectionProxy::TPushPop env(const_cast<TEmulatedCollectionProxy*>(this), p);
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 
99 void 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].c_str());
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  int slong = sizeof(void*);
140  switch ( fSTL_type ) {
141  case ROOT::kSTLmap:
142  case ROOT::kSTLmultimap:
143  nam = "pair<"+inside[1]+","+inside[2];
144  nam += (nam[nam.length()-1]=='>') ? " >" : ">";
145  if (0==TClass::GetClass(nam.c_str())) {
146  // We need to emulate the pair
147  R__GenerateTClassForPair(inside[1],inside[2]);
148  }
149  fValue = new Value(nam,silent);
150  fKey = new Value(inside[1],silent);
151  fVal = new Value(inside[2],silent);
152  if ( !(*fValue).IsValid() || !fKey->IsValid() || !fVal->IsValid() ) {
153  return 0;
154  }
155  fPointers |= 0 != (fKey->fCase&kIsPointer);
156  if (fPointers || (0 != (fKey->fProperties&kNeedDelete))) {
158  }
159  if ( 0 == fValDiff ) {
160  fValDiff = fKey->fSize + fVal->fSize;
161  fValDiff += (slong - fKey->fSize%slong)%slong;
162  fValDiff += (slong - fValDiff%slong)%slong;
163  }
164  if ( 0 == fValOffset ) {
165  fValOffset = fKey->fSize;
166  fValOffset += (slong - fKey->fSize%slong)%slong;
167  }
168  break;
169  case ROOT::kSTLbitset:
170  inside[1] = "bool";
171  // Intentional fall through
172  default:
173  fValue = new Value(inside[1],silent);
174  fVal = new Value(*fValue);
175  if ( !(*fValue).IsValid() || !fVal->IsValid() ) {
176  return 0;
177  }
178  if ( 0 == fValDiff ) {
179  fValDiff = fVal->fSize;
180  if (fVal->fCase != kIsFundamental) {
181  fValDiff += (slong - fValDiff%slong)%slong;
182  }
183  }
184  break;
185  }
186  fPointers |= 0 != (fVal->fCase&kIsPointer);
187  if (fPointers || (0 != (fVal->fProperties&kNeedDelete))) {
189  }
190  fClass = cl;
191  return this;
192  }
193  Fatal("TEmulatedCollectionProxy","Components of %s not analysed!",cl->GetName());
194  }
195  Fatal("TEmulatedCollectionProxy","Collection class %s not found!",fTypeinfo.name());
196  return 0;
197 }
198 
200 {
201  // Return true if the collection proxy was well initialized.
202  return (0 != fCreateEnv.call);
203 }
204 
206 {
207  // Return the current size of the container
208 
209  if ( fEnv && fEnv->fObject ) {
210  return fEnv->fSize = PCont_t(fEnv->fObject)->size()/fValDiff;
211  }
212  Fatal("TEmulatedCollectionProxy","Size> Logic error - no proxy object set.");
213  return 0;
214 }
215 
216 void TEmulatedCollectionProxy::Clear(const char* opt)
217 {
218  // Clear the emulated collection.
219  Resize(0, opt && *opt=='f');
220 }
221 
223 {
224  // Shrink the container
225 
226  typedef std::string String_t;
228  char* addr = ((char*)fEnv->fStart) + fValDiff*left;
229  size_t i;
230 
231  switch ( fSTL_type ) {
232  case ROOT::kSTLmap:
233  case ROOT::kSTLmultimap:
234  addr = ((char*)fEnv->fStart) + fValDiff*left;
235  switch(fKey->fCase) {
236  case kIsFundamental: // Only handle primitives this way
237  case kIsEnum:
238  break;
239  case kIsClass:
240  for( i= fKey->fType ? left : nCurr; i<nCurr; ++i, addr += fValDiff ) {
241  // Call emulation in case non-compiled content
242  fKey->fType->Destructor(addr, kTRUE);
243  }
244  break;
245  case kBIT_ISSTRING:
246  for( i=left; i<nCurr; ++i, addr += fValDiff ) {
247  ((std::string*)addr)->~String_t();
248  }
249  break;
250  case kIsPointer|kIsClass:
251  for( i=left; i<nCurr; ++i, addr += fValDiff ) {
252  StreamHelper* h = (StreamHelper*)addr;
253  //Eventually we'll need to delete this
254  //(but only when needed).
255  void* ptr = h->ptr();
256  if (force) fKey->fType->Destructor(ptr);
257  h->set(0);
258  }
259  break;
261  for( i=nCurr; i<left; ++i, addr += fValDiff ) {
262  StreamHelper* h = (StreamHelper*)addr;
263  //Eventually we'll need to delete this
264  //(but only when needed).
265  if (force) delete (std::string*)h->ptr();
266  h->set(0);
267  }
268  break;
270  for( i=nCurr; i<left; ++i, addr += fValDiff ) {
271  StreamHelper* h = (StreamHelper*)addr;
272  if (force) delete (TString*)h->ptr();
273  h->set(0);
274  }
275  break;
276  }
277  addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*left;
278  // DO NOT break; just continue
279 
280  // General case for all values
281  default:
282  switch( fVal->fCase ) {
283  case kIsFundamental: // Only handle primitives this way
284  case kIsEnum:
285  break;
286  case kIsClass:
287  for( i=left; i<nCurr; ++i, addr += fValDiff ) {
288  // Call emulation in case non-compiled content
289  fVal->fType->Destructor(addr,kTRUE);
290  }
291  break;
292  case kBIT_ISSTRING:
293  for( i=left; i<nCurr; ++i, addr += fValDiff )
294  ((std::string*)addr)->~String_t();
295  break;
296  case kIsPointer|kIsClass:
297  for( i=left; i<nCurr; ++i, addr += fValDiff ) {
298  StreamHelper* h = (StreamHelper*)addr;
299  void* p = h->ptr();
300  if ( p && force ) {
301  fVal->fType->Destructor(p);
302  }
303  h->set(0);
304  }
305  break;
307  for( i=nCurr; i<left; ++i, addr += fValDiff ) {
308  StreamHelper* h = (StreamHelper*)addr;
309  if (force) delete (std::string*)h->ptr();
310  h->set(0);
311  }
312  break;
314  for( i=nCurr; i<left; ++i, addr += fValDiff ) {
315  StreamHelper* h = (StreamHelper*)addr;
316  if (force) delete (TString*)h->ptr();
317  h->set(0);
318  }
319  break;
320  }
321  }
322  c->resize(left*fValDiff,0);
323  fEnv->fStart = left>0 ? &(*c->begin()) : 0;
324  return;
325 }
326 
328 {
329  // Expand the container
330  size_t i;
332  c->resize(left*fValDiff,0);
333  void *oldstart = fEnv->fStart;
334  fEnv->fStart = left>0 ? &(*c->begin()) : 0;
335 
336  char* addr = ((char*)fEnv->fStart) + fValDiff*nCurr;
337  switch ( fSTL_type ) {
338  case ROOT::kSTLmap:
339  case ROOT::kSTLmultimap:
340  switch(fKey->fCase) {
341  case kIsFundamental: // Only handle primitives this way
342  case kIsEnum:
343  break;
344  case kIsClass:
345  if (oldstart && oldstart != fEnv->fStart) {
346  Long_t offset = 0;
347  for( i=0; i<=nCurr; ++i, offset += fValDiff ) {
348  // For now 'Move' only register the change of location
349  // so per se this is wrong since the object are copied via memcpy
350  // rather than a copy (or move) constructor.
351  fKey->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
352  }
353  }
354  for( i=nCurr; i<left; ++i, addr += fValDiff )
355  fKey->fType->New(addr);
356  break;
357  case kBIT_ISSTRING:
358  for( i=nCurr; i<left; ++i, addr += fValDiff )
359  ::new(addr) std::string();
360  break;
361  case kIsPointer|kIsClass:
364  for( i=nCurr; i<left; ++i, addr += fValDiff )
365  *(void**)addr = 0;
366  break;
367  }
368  addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*nCurr;
369  // DO NOT break; just continue
370 
371  // General case for all values
372  default:
373  switch(fVal->fCase) {
374  case kIsFundamental: // Only handle primitives this way
375  case kIsEnum:
376  break;
377  case kIsClass:
378  if (oldstart && oldstart != fEnv->fStart) {
379  Long_t offset = 0;
380  for( i=0; i<=nCurr; ++i, offset += fValDiff ) {
381  // For now 'Move' only register the change of location
382  // so per se this is wrong since the object are copied via memcpy
383  // rather than a copy (or move) constructor.
384  fVal->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
385  }
386  }
387  for( i=nCurr; i<left; ++i, addr += fValDiff ) {
388  fVal->fType->New(addr);
389  }
390  break;
391  case kBIT_ISSTRING:
392  for( i=nCurr; i<left; ++i, addr += fValDiff )
393  ::new(addr) std::string();
394  break;
395  case kIsPointer|kIsClass:
398  for( i=nCurr; i<left; ++i, addr += fValDiff )
399  *(void**)addr = 0;
400  break;
401  }
402  break;
403  }
404 }
405 
407 {
408  // Resize the container
409 
410  if ( fEnv && fEnv->fObject ) {
411  size_t nCurr = Size();
413  fEnv->fStart = nCurr>0 ? &(*c->begin()) : 0;
414  if ( left == nCurr ) {
415  return;
416  }
417  else if ( left < nCurr ) {
418  Shrink(nCurr, left, force);
419  return;
420  }
421  Expand(nCurr, left);
422  return;
423  }
424  Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set.");
425 }
426 
428 {
429  // Return the address of the value at index 'idx'
430  if ( fEnv && fEnv->fObject ) {
432  size_t s = c->size();
433  if ( idx >= (s/fValDiff) ) {
434  return 0;
435  }
436  return idx<(s/fValDiff) ? ((char*)&(*c->begin()))+idx*fValDiff : 0;
437  }
438  Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set.");
439  return 0;
440 }
441 
443 {
444  // Allocate the necessary space.
445 
446  Resize(n, forceDelete);
447  return fEnv->fObject;
448 }
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 /// Insert data into the container where data is a C-style array of the actual type contained in the collection
452 /// of the given size. For associative container (map, etc.), the data type is the pair<key,value>.
453 
454 void TEmulatedCollectionProxy::Insert(const void * /* data */, void * /*container*/, size_t /*size*/)
455 {
456  Fatal("Insert","Not yet implemented, require copy of objects.");
457 }
458 
459 void TEmulatedCollectionProxy::Commit(void* /* env */ )
460 {
461 }
462 
464 {
465  // Object input streamer
466  Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
467  StreamHelper* itm = (StreamHelper*)At(0);
468  switch (fVal->fCase) {
469  case kIsFundamental: // Only handle primitives this way
470  case kIsEnum:
471  switch( int(fVal->fKind) ) {
472  case kBool_t: b.ReadFastArray(&itm->boolean , nElements); break;
473  case kChar_t: b.ReadFastArray(&itm->s_char , nElements); break;
474  case kShort_t: b.ReadFastArray(&itm->s_short , nElements); break;
475  case kInt_t: b.ReadFastArray(&itm->s_int , nElements); break;
476  case kLong_t: b.ReadFastArray(&itm->s_long , nElements); break;
477  case kLong64_t: b.ReadFastArray(&itm->s_longlong, nElements); break;
478  case kFloat_t: b.ReadFastArray(&itm->flt , nElements); break;
479  case kFloat16_t: b.ReadFastArrayFloat16(&itm->flt, nElements); break;
480  case kDouble_t: b.ReadFastArray(&itm->dbl , nElements); break;
481  case kBOOL_t: b.ReadFastArray(&itm->boolean , nElements); break;
482  case kUChar_t: b.ReadFastArray(&itm->u_char , nElements); break;
483  case kUShort_t: b.ReadFastArray(&itm->u_short , nElements); break;
484  case kUInt_t: b.ReadFastArray(&itm->u_int , nElements); break;
485  case kULong_t: b.ReadFastArray(&itm->u_long , nElements); break;
486  case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
487  case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
488  case kchar:
489  case kNoType_t:
490  case kOther_t:
491  Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
492  }
493  break;
494 
495 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
496 
497  case kIsClass:
498  DOLOOP( b.StreamObject(i,fVal->fType) );
499  case kBIT_ISSTRING:
500  DOLOOP( i->read_std_string(b) );
501  case kIsPointer|kIsClass:
502  DOLOOP( i->read_any_object(fVal,b) );
504  DOLOOP( i->read_std_string_pointer(b) );
506  DOLOOP( i->read_tstring_pointer(vsn3,b) );
507  }
508 
509 #undef DOLOOP
510 
511 }
512 
514 {
515  // Object output streamer
516  StreamHelper* itm = (StreamHelper*)At(0);
517  switch (fVal->fCase) {
518  case kIsFundamental: // Only handle primitives this way
519  case kIsEnum:
520  itm = (StreamHelper*)At(0);
521  switch( int(fVal->fKind) ) {
522  case kBool_t: b.WriteFastArray(&itm->boolean , nElements); break;
523  case kChar_t: b.WriteFastArray(&itm->s_char , nElements); break;
524  case kShort_t: b.WriteFastArray(&itm->s_short , nElements); break;
525  case kInt_t: b.WriteFastArray(&itm->s_int , nElements); break;
526  case kLong_t: b.WriteFastArray(&itm->s_long , nElements); break;
527  case kLong64_t: b.WriteFastArray(&itm->s_longlong, nElements); break;
528  case kFloat_t: b.WriteFastArray(&itm->flt , nElements); break;
529  case kFloat16_t: b.WriteFastArrayFloat16(&itm->flt, nElements); break;
530  case kDouble_t: b.WriteFastArray(&itm->dbl , nElements); break;
531  case kBOOL_t: b.WriteFastArray(&itm->boolean , nElements); break;
532  case kUChar_t: b.WriteFastArray(&itm->u_char , nElements); break;
533  case kUShort_t: b.WriteFastArray(&itm->u_short , nElements); break;
534  case kUInt_t: b.WriteFastArray(&itm->u_int , nElements); break;
535  case kULong_t: b.WriteFastArray(&itm->u_long , nElements); break;
536  case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
537  case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
538  case kchar:
539  case kNoType_t:
540  case kOther_t:
541  Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
542  }
543  break;
544 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
545  case kIsClass:
546  DOLOOP( b.StreamObject(i,fVal->fType) );
547  case kBIT_ISSTRING:
548  DOLOOP( TString(i->c_str()).Streamer(b) );
549  case kIsPointer|kIsClass:
550  DOLOOP( b.WriteObjectAny(i->ptr(),fVal->fType) );
552  DOLOOP( i->write_std_string_pointer(b) );
554  DOLOOP( i->write_tstring_pointer(b) );
555  }
556 #undef DOLOOP
557 }
558 
559 void TEmulatedCollectionProxy::ReadBuffer(TBuffer &b, void *obj, const TClass *onfileClass)
560 {
561  // Read portion of the streamer.
562 
563  SetOnFileClass((TClass*)onfileClass);
564  ReadBuffer(b,obj);
565 }
566 
568 {
569  // Read portion of the streamer.
570 
571  TPushPop env(this,obj);
572  int nElements = 0;
573  b >> nElements;
574  if ( fEnv->fObject ) {
575  Resize(nElements,true);
576  }
577  if ( nElements > 0 ) {
578  ReadItems(nElements, b);
579  }
580 }
581 
583 {
584  // TClassStreamer IO overload
585  if ( b.IsReading() ) { //Read mode
586  int nElements = 0;
587  b >> nElements;
588  if ( fEnv->fObject ) {
589  Resize(nElements,true);
590  }
591  if ( nElements > 0 ) {
592  ReadItems(nElements, b);
593  }
594  }
595  else { // Write case
596  int nElements = fEnv->fObject ? Size() : 0;
597  b << nElements;
598  if ( nElements > 0 ) {
599  WriteItems(nElements, b);
600  }
601  }
602 }
603 
604 //
605 // Utility functions
606 //
607 static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset)
608 {
609  // Create a TStreamerElement for the type 'dmFull' and whose data member name is 'dmName'.
610 
611  TString s1( TClassEdit::ShortType(dmFull,0) );
612  TString dmType( TClassEdit::ShortType(dmFull,1) );
613  Bool_t dmIsPtr = (s1 != dmType);
614  const char *dmTitle = "Emulation";
615 
616  TDataType *dt = gROOT->GetType(dmType);
617  if (dt && dt->GetType() > 0 ) { // found a basic type
618  Int_t dsize,dtype;
619  dtype = dt->GetType();
620  dsize = dt->Size();
621  if (dmIsPtr && dtype != kCharStar) {
622  Error("Pair Emulation Building","%s is not yet supported in pair emulation",
623  dmFull);
624  return 0;
625  } else {
626  TStreamerElement *el = new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull);
627  el->SetSize(dsize);
628  return el;
629  }
630  } else {
631 
632  static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
633  if (strcmp(dmType,"string") == 0 || strcmp(dmType,"std::string") == 0 || strcmp(dmType,full_string_name)==0 ) {
634  return new TStreamerSTLstring(dmName,dmTitle,offset,dmFull,dmIsPtr);
635  }
636  if (TClassEdit::IsSTLCont(dmType)) {
637  return new TStreamerSTL(dmName,dmTitle,offset,dmFull,dmFull,dmIsPtr);
638  }
639  TClass *clm = TClass::GetClass(dmType);
640  if (!clm) {
641  // either we have an Emulated enum or a really unknown class!
642  // let's just claim its an enum :(
643  Int_t dtype = kInt_t;
644  return new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull);
645  }
646  // a pointer to a class
647  if ( dmIsPtr ) {
648  if (clm->IsTObject()) {
649  return new TStreamerObjectPointer(dmName,dmTitle,offset,dmFull);
650  } else {
651  return new TStreamerObjectAnyPointer(dmName,dmTitle,offset,dmFull);
652  }
653  }
654  // a class
655  if (clm->IsTObject()) {
656  return new TStreamerObject(dmName,dmTitle,offset,dmFull);
657  } else if(clm == TString::Class() && !dmIsPtr) {
658  return new TStreamerString(dmName,dmTitle,offset);
659  } else {
660  return new TStreamerObjectAny(dmName,dmTitle,offset,dmFull);
661  }
662  }
663 }
664 
665 
666 static TStreamerInfo *R__GenerateTClassForPair(const std::string &fname, const std::string &sname)
667 {
668  // Generate a TStreamerInfo for a std::pair<fname,sname>
669  // This TStreamerInfo is then used as if it was read from a file to generate
670  // and emulated TClass.
671 
672  TStreamerInfo *i = (TStreamerInfo*)TClass::GetClass("pair<const int,int>")->GetStreamerInfo()->Clone();
673  std::string pname = "pair<"+fname+","+sname;
674  pname += (pname[pname.length()-1]=='>') ? " >" : ">";
675  i->SetName(pname.c_str());
676  i->SetClass(0);
677  i->GetElements()->Delete();
678  TStreamerElement *fel = R__CreateEmulatedElement("first", fname.c_str(), 0);
679  Int_t size = 0;
680  if (fel) {
681  i->GetElements()->Add( fel );
682 
683  size = fel->GetSize();
684  Int_t sp = sizeof(void *);
685  //align the non-basic data types (required on alpha and IRIX!!)
686  if (size%sp != 0) size = size - size%sp + sp;
687  } else {
688  delete i;
689  return 0;
690  }
691  TStreamerElement *second = R__CreateEmulatedElement("second", sname.c_str(), size);
692  if (second) {
693  i->GetElements()->Add( second );
694  } else {
695  delete i;
696  return 0;
697  }
698  Int_t oldlevel = gErrorIgnoreLevel;
699  // Hide the warning about the missing pair dictionary.
701  i->BuildCheck();
702  gErrorIgnoreLevel = oldlevel;
703  i->BuildOld();
704  return i;
705 }
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
void Expand(UInt_t nCurr, UInt_t left)
virtual void WriteFastArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele=0)=0
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:107
UInt_t fProperties
Additional properties of the value type (kNeedDelete)
Bool_t IsReading() const
Definition: TBuffer.h:83
Int_t GetType() const
Definition: TDataType.h:70
void Fatal(const char *location, const char *msgfmt,...)
virtual void SetSize(Int_t dsize)
Bool_t fPointers
Flag to indicate if containee has pointers (key or value)
TGenCollectionProxy * Initialize(Bool_t silent) const
Proxy initializer.
return c
virtual void StreamObject(void *obj, const type_info &typeinfo, const TClass *onFileClass=0)=0
std::string fName
Name of the class being proxied.
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:329
tuple offset
Definition: tree.py:93
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the splited type.
Definition: TClassEdit.cxx:927
static TStreamerElement * R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset)
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:46
virtual Int_t WriteObjectAny(const void *obj, const TClass *ptrClass)=0
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
TH1 * h
Definition: legend2.C:5
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5462
tuple pname
Definition: tree.py:131
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
#define gROOT
Definition: TROOT.h:344
virtual Int_t GetSize() const
Returns size of this element in bytes.
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
#define DOLOOP(x)
Definition: drr.cxx:518
UInt_t fCase
type of data of Value_type
Streamer around an arbitrary STL like container, which implements basic container functionality...
virtual TVirtualStreamerInfo * GetInfo()=0
TFile * f
size_t fSize
fSize of the contained object
TSocket * s1
Definition: hserv2.C:36
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:3980
void Class()
Definition: Class.C:29
TEmulatedCollectionProxy(const TEmulatedCollectionProxy &copy)
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4602
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
Definition: TClassEdit.cxx:467
void SetClass(TClass *cl)
virtual void * Allocate(UInt_t n, Bool_t forceDelete)
Allocate the needed space.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
Method0 fCreateEnv
Method to allocate an Environment holder.
void Error(const char *location, const char *msgfmt,...)
EDataType fKind
kind of ROOT-fundamental type
virtual void Resize(UInt_t n, Bool_t force_delete)
Resize the container.
int fValOffset
Offset from key to value (in maps)
TObjArray * GetElements() const
void BuildOld()
rebuild the TStreamerInfo structure
virtual void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=0)=0
int fSTL_type
STL container type.
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:4256
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:46
virtual void Clear(const char *opt="")
Clear the emulated collection.
virtual TVirtualCollectionProxy * Generate() const
Virtual copy constructor.
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:4959
virtual void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=0)=0
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual TGenCollectionProxy * InitializeEx(Bool_t silent)
Proxy initializer.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
const std::string sname
Definition: testIO.cxx:45
void Warning(const char *location, const char *msgfmt,...)
void WriteItems(int nElements, TBuffer &b)
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
virtual void WriteFastArray(const Bool_t *b, Int_t n)=0
int fValDiff
Offset between two consecutive value_types (memory layout).
long Long_t
Definition: RtypesCore.h:50
virtual void Commit(void *env)
Commit the change.
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...
void Shrink(UInt_t nCurr, UInt_t left, Bool_t force)
virtual Version_t GetOldVersion() const =0
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:2801
std::atomic< Value * > fValue
Descriptor of the container value type.
TClassRef fType
TClass reference of Value_type in collection.
virtual void SetOnFileClass(TClass *cl)
static TStreamerInfo * R__GenerateTClassForPair(const std::string &f, const std::string &s)
Int_t Size() const
Get size of basic typedef'ed type.
Definition: TDataType.cxx:362
Value * fKey
Descriptor of the key_type.
void ReadItems(int nElements, TBuffer &b)
void BuildCheck(TFile *file=0)
Check if built and consistent with the class dictionary.
Helper class to facilitate I/O.
Proxy around an arbitrary container, which implements basic functionality and iteration.
EnvironBase_t * fEnv
Address of the currently proxied object.
virtual UInt_t Size() const
Return the current size of the container.
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
const Int_t kError
Definition: TError.h:41
virtual void * At(UInt_t idx)
Return the address of the value at index 'idx'.
Bool_t IsValid()
Return true if the Value has been properly initialized.
void Add(TObject *obj)
Definition: TObjArray.h:75
virtual void ReadBuffer(TBuffer &buff, void *pObj)
Info_t fTypeinfo
Type information.
virtual void Destructor(void *p, Bool_t dtorOnly=kFALSE) const
virtual void Streamer(TBuffer &refBuffer)
Streamer Function.
const Bool_t kTRUE
Definition: Rtypes.h:91
TObject * obj
virtual void DeleteArray(void *p, Bool_t dtorOnly=kFALSE) const
const Int_t n
Definition: legend1.C:16
virtual void WriteFastArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele=0)=0
const char * Value
Definition: TXMLSetup.cxx:73
Value * fVal
Descriptor of the Value_type.