Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TObject.cxx
Go to the documentation of this file.
1// @(#)root/base:$Id$
2// Author: Rene Brun 26/12/94
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/** \class TObject
13\ingroup Base
14
15Mother of all ROOT objects.
16
17The TObject class provides default behaviour and protocol for all
18objects in the ROOT system. It provides protocol for object I/O,
19error handling, sorting, inspection, printing, drawing, etc.
20Every object which inherits from TObject can be stored in the
21ROOT collection classes.
22
23TObject's bits can be used as flags, bits 0 - 13 and 24-31 are
24reserved as global bits while bits 14 - 23 can be used in different
25class hierarchies (watch out for overlaps).
26*/
27
28#include <cstring>
29#if !defined(WIN32) && !defined(__MWERKS__) && !defined(R__SOLARIS)
30#include <strings.h>
31#endif
32#include <cstdlib>
33#include <cstdio>
34#include <sstream>
35#include <fstream>
36#include <iostream>
37
38#include "Varargs.h"
39#include "snprintf.h"
40#include "TObject.h"
41#include "TBuffer.h"
42#include "TClass.h"
43#include "TGuiFactory.h"
44#include "TMethod.h"
45#include "TROOT.h"
46#include "TError.h"
47#include "TObjectTable.h"
48#include "TVirtualPad.h"
49#include "TInterpreter.h"
50#include "TMemberInspector.h"
51#include "TRefTable.h"
52#include "TProcessID.h"
53
56
58
59namespace ROOT {
60namespace Internal {
61
62// Return true if delete changes/poisons/taints the memory.
63//
64// Detect whether operator delete taints the memory. If it does, we can not rely
65// on TestBit(kNotDeleted) to check if the memory has been deleted (but in case,
66// like TClonesArray, where we know the destructor will be called but not operator
67// delete, we can still use it to detect the cases where the destructor was called.
68
70{
71 static constexpr UInt_t kGoldenUUID = 0x00000021;
72 static constexpr UInt_t kGoldenbits = 0x03000000;
74 TObject *o = new TObject;
75 o->SetUniqueID(kGoldenUUID);
76 UInt_t *o_fuid = &(o->fUniqueID);
77 UInt_t *o_fbits = &(o->fBits);
78
79 if (*o_fuid != kGoldenUUID) {
80 Error("CheckingDeleteSideEffects",
81 "fUniqueID is not as expected, we got 0x%.8x instead of 0x%.8x",
82 *o_fuid, kGoldenUUID);
83 }
84 if (*o_fbits != kGoldenbits) {
85 Error("CheckingDeleteSideEffects",
86 "fBits is not as expected, we got 0x%.8x instead of 0x%.8x",
87 *o_fbits, kGoldenbits);
88 }
89 if (gDebug >= 9) {
90 unsigned char *oc = reinterpret_cast<unsigned char *>(o); // for address calculations
91 unsigned char references[sizeof(TObject)];
92 memcpy(references, oc, sizeof(TObject));
93
94 // The effective part of this code (the else statement is just that without
95 // any of the debug statement)
96 delete o;
97
98 // Not using the error logger, as there routine is meant to be called
99 // during library initialization/loading.
100 fprintf(stderr,
101 "DEBUG: Checking before and after delete the content of a TObject with uniqueID 0x21\n");
102 for(size_t i = 0; i < sizeof(TObject); i += 4) {
103 fprintf(stderr, "DEBUG: 0x%.8x vs 0x%.8x\n", *(int*)(references +i), *(int*)(oc + i));
104 }
105 } else
106 delete o; // the 'if' part is that surrounded by the debug code.
107
108 // Intentionally accessing the deleted memory to check whether it has been changed as
109 // a consequence (side effect) of executing operator delete. If there no change, we
110 // can guess this is always the case and we can rely on the changes to fBits made
111 // by ~TObject to detect use-after-delete error (and print a message rather than
112 // stop the program with a segmentation fault)
113 if ( *o_fbits != 0x01000000 ) {
114 // operator delete tainted the memory, we can not rely on TestBit(kNotDeleted)
115 return true;
116 }
117 return false;
118}
119
121{
122 static const bool value = DeleteChangesMemoryImpl();
123 if (gDebug >= 9)
124 DeleteChangesMemoryImpl(); // To allow for printing the debug info
125 return value;
126}
127
128}} // ROOT::Detail
129
130////////////////////////////////////////////////////////////////////////////////
131/// Copy this to obj.
132
133void TObject::Copy(TObject &obj) const
134{
135 obj.fUniqueID = fUniqueID; // when really unique don't copy
136 if (obj.IsOnHeap()) { // test uses fBits so don't move next line
137 obj.fBits = fBits;
138 obj.fBits |= kIsOnHeap;
139 } else {
140 obj.fBits = fBits;
141 obj.fBits &= ~kIsOnHeap;
142 }
143 obj.fBits &= ~kIsReferenced;
144 obj.fBits &= ~kCanDelete;
145}
146
147////////////////////////////////////////////////////////////////////////////////
148/// TObject destructor. Removes object from all canvases and object browsers
149/// if observer bit is on and remove from the global object table.
150
152{
153 // if (!TestBit(kNotDeleted))
154 // Fatal("~TObject", "object deleted twice");
155
157
158 fBits &= ~kNotDeleted;
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Private helper function which will dispatch to
165/// TObjectTable::AddObj.
166/// Included here to avoid circular dependency between header files.
167
169{
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Append graphics object to current pad. In case no current pad is set
175/// yet, create a default canvas with the name "c1".
176
178{
179 if (!gPad) {
180 gROOT->MakeDefCanvas();
181 }
182 if (!gPad->IsEditable()) return;
184 gPad->GetListOfPrimitives()->Add(this,option);
185 gPad->Modified(kTRUE);
186}
187
188////////////////////////////////////////////////////////////////////////////////
189/// Browse object. May be overridden for another default action
190
192{
193 //Inspect();
194 TClass::AutoBrowse(this,b);
195}
196
197////////////////////////////////////////////////////////////////////////////////
198/// Returns name of class to which the object belongs.
199
200const char *TObject::ClassName() const
201{
202 return IsA()->GetName();
203}
204
205////////////////////////////////////////////////////////////////////////////////
206/// Make a clone of an object using the Streamer facility.
207/// If the object derives from TNamed, this function is called
208/// by TNamed::Clone. TNamed::Clone uses the optional argument to set
209/// a new name to the newly created object.
210///
211/// If the object class has a DirectoryAutoAdd function, it will be
212/// called at the end of the function with the parameter gDirectory.
213/// This usually means that the object will be appended to the current
214/// ROOT directory.
215
216TObject *TObject::Clone(const char *) const
217{
218 if (gDirectory) {
219 return gDirectory->CloneObject(this);
220 } else {
221 // Some of the streamer (eg. roofit's) expect(ed?) a valid gDirectory during streaming.
222 return gROOT->CloneObject(this);
223 }
224}
225
226////////////////////////////////////////////////////////////////////////////////
227/// Compare abstract method. Must be overridden if a class wants to be able
228/// to compare itself with other objects. Must return -1 if this is smaller
229/// than obj, 0 if objects are equal and 1 if this is larger than obj.
230
232{
233 AbstractMethod("Compare");
234 return 0;
235}
236
237////////////////////////////////////////////////////////////////////////////////
238/// Delete this object. Typically called as a command via the interpreter.
239/// Normally use "delete" operator when object has been allocated on the heap.
240
242{
243 if (IsOnHeap()) {
244 // Delete object from CINT symbol table so it can not be used anymore.
245 // CINT object are always on the heap.
246 gInterpreter->DeleteGlobal(this);
247
248 delete this;
249 }
250}
251
252
253////////////////////////////////////////////////////////////////////////////////
254/// Computes distance from point (px,py) to the object.
255/// This member function must be implemented for each graphics primitive.
256/// This default function returns a big number (999999).
257
259{
260 // AbstractMethod("DistancetoPrimitive");
261 return 999999;
262}
263
264////////////////////////////////////////////////////////////////////////////////
265/// Default Draw method for all objects
266
268{
269 AppendPad(option);
270}
271
272////////////////////////////////////////////////////////////////////////////////
273/// Draw class inheritance tree of the class to which this object belongs.
274/// If a class B inherits from a class A, description of B is drawn
275/// on the right side of description of A.
276/// Member functions overridden by B are shown in class A with a blue line
277/// crossing-out the corresponding member function.
278/// The following picture is the class inheritance tree of class TPaveLabel:
279///
280/// \image html base_object.png
281
283{
284 IsA()->Draw();
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Draw a clone of this object in the current selected pad for instance with:
289/// `gROOT->SetSelectedPad(gPad)`.
290
292{
294 TVirtualPad *padsav = gPad;
295 if (pad) pad->cd();
296
297 TObject *newobj = Clone();
298 if (!newobj) return nullptr;
299 if (pad) {
300 if (strlen(option)) pad->GetListOfPrimitives()->Add(newobj,option);
301 else pad->GetListOfPrimitives()->Add(newobj,GetDrawOption());
302 pad->Modified(kTRUE);
303 pad->Update();
304 if (padsav) padsav->cd();
305 return newobj;
306 }
307 if (strlen(option)) newobj->Draw(option);
308 else newobj->Draw(GetDrawOption());
309 if (padsav) padsav->cd();
310
311 return newobj;
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Dump contents of object on stdout.
316/// Using the information in the object dictionary (class TClass)
317/// each data member is interpreted.
318/// If a data member is a pointer, the pointer value is printed
319///
320/// The following output is the Dump of a TArrow object:
321/// ~~~ {.cpp}
322/// fAngle 0 Arrow opening angle (degrees)
323/// fArrowSize 0.2 Arrow Size
324/// fOption.*fData
325/// fX1 0.1 X of 1st point
326/// fY1 0.15 Y of 1st point
327/// fX2 0.67 X of 2nd point
328/// fY2 0.83 Y of 2nd point
329/// fUniqueID 0 object unique identifier
330/// fBits 50331648 bit field status word
331/// fLineColor 1 line color
332/// fLineStyle 1 line style
333/// fLineWidth 1 line width
334/// fFillColor 19 fill area color
335/// fFillStyle 1001 fill area style
336/// ~~~
337
338void TObject::Dump() const
339{
340 // Get the actual address of the object.
341 const void *actual = IsA()->DynamicCast(TObject::Class(),this,kFALSE);
342 IsA()->Dump(actual);
343}
344
345////////////////////////////////////////////////////////////////////////////////
346/// Execute method on this object with the given parameter string, e.g.
347/// "3.14,1,\"text\"".
348
349void TObject::Execute(const char *method, const char *params, Int_t *error)
350{
351 if (!IsA()) return;
352
353 Bool_t must_cleanup = TestBit(kMustCleanup);
354
355 gInterpreter->Execute(this, IsA(), method, params, error);
356
357 if (gPad && must_cleanup) gPad->Modified();
358}
359
360////////////////////////////////////////////////////////////////////////////////
361/// Execute method on this object with parameters stored in the TObjArray.
362/// The TObjArray should contain an argv vector like:
363/// ~~~ {.cpp}
364/// argv[0] ... argv[n] = the list of TObjString parameters
365/// ~~~
366
367void TObject::Execute(TMethod *method, TObjArray *params, Int_t *error)
368{
369 if (!IsA()) return;
370
371 Bool_t must_cleanup = TestBit(kMustCleanup);
372
373 gInterpreter->Execute(this, IsA(), method, params, error);
374
375 if (gPad && must_cleanup) gPad->Modified();
376}
377
378
379////////////////////////////////////////////////////////////////////////////////
380/// Execute action corresponding to an event at (px,py). This method
381/// must be overridden if an object can react to graphics events.
382
384{
385 // AbstractMethod("ExecuteEvent");
386}
387
388////////////////////////////////////////////////////////////////////////////////
389/// Must be redefined in derived classes.
390/// This function is typically used with TCollections, but can also be used
391/// to find an object by name inside this object.
392
393TObject *TObject::FindObject(const char *) const
394{
395 return nullptr;
396}
397
398////////////////////////////////////////////////////////////////////////////////
399/// Must be redefined in derived classes.
400/// This function is typically used with TCollections, but can also be used
401/// to find an object inside this object.
402
404{
405 return nullptr;
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Get option used by the graphics system to draw this object.
410/// Note that before calling object.GetDrawOption(), you must
411/// have called object.Draw(..) before in the current pad.
412
414{
415 if (!gPad) return "";
416
417 TListIter next(gPad->GetListOfPrimitives());
418 TObject *obj;
419 while ((obj = next())) {
420 if (obj == this) return next.GetOption();
421 }
422 return "";
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Returns name of object. This default method returns the class name.
427/// Classes that give objects a name should override this method.
428
429const char *TObject::GetName() const
430{
431 return IsA()->GetName();
432}
433
434////////////////////////////////////////////////////////////////////////////////
435/// Returns mime type name of object. Used by the TBrowser (via TGMimeTypes
436/// class). Override for class of which you would like to have different
437/// icons for objects of the same class.
438
439const char *TObject::GetIconName() const
440{
441 return nullptr;
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Return the unique object id.
446
448{
449 return fUniqueID;
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Returns string containing info about the object at position (px,py).
454/// This method is typically overridden by classes of which the objects
455/// can report peculiarities for different positions.
456/// Returned string will be re-used (lock in MT environment).
457
459{
460 if (!gPad) return (char*)"";
461 static char info[64];
462 Float_t x = gPad->AbsPixeltoX(px);
463 Float_t y = gPad->AbsPixeltoY(py);
464 snprintf(info,64,"x=%g, y=%g",gPad->PadtoX(x),gPad->PadtoY(y));
465 return info;
466}
467
468////////////////////////////////////////////////////////////////////////////////
469/// Returns title of object. This default method returns the class title
470/// (i.e. description). Classes that give objects a title should override
471/// this method.
472
473const char *TObject::GetTitle() const
474{
475 return IsA()->GetTitle();
476}
477
478
479////////////////////////////////////////////////////////////////////////////////
480/// Execute action in response of a timer timing out. This method
481/// must be overridden if an object has to react to timers.
482
484{
485 return kFALSE;
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// Return hash value for this object.
490///
491/// Note: If this routine is overloaded in a derived class, this derived class
492/// should also add
493/// ~~~ {.cpp}
494/// ROOT::CallRecursiveRemoveIfNeeded(*this)
495/// ~~~
496/// Otherwise, when RecursiveRemove is called (by ~TObject or example) for this
497/// type of object, the transversal of THashList and THashTable containers will
498/// will have to be done without call Hash (and hence be linear rather than
499/// logarithmic complexity). You will also see warnings like
500/// ~~~
501/// Error in <ROOT::Internal::TCheckHashRecursiveRemoveConsistency::CheckRecursiveRemove>: The class SomeName overrides TObject::Hash but does not call TROOT::RecursiveRemove in its destructor.
502/// ~~~
503///
504
506{
507 //return (ULong_t) this >> 2;
508 const void *ptr = this;
509 return TString::Hash(&ptr, sizeof(void*));
510}
511
512////////////////////////////////////////////////////////////////////////////////
513/// Returns kTRUE if object inherits from class "classname".
514
515Bool_t TObject::InheritsFrom(const char *classname) const
516{
517 return IsA()->InheritsFrom(classname);
518}
519
520////////////////////////////////////////////////////////////////////////////////
521/// Returns kTRUE if object inherits from TClass cl.
522
524{
525 return IsA()->InheritsFrom(cl);
526}
527
528////////////////////////////////////////////////////////////////////////////////
529/// Dump contents of this object in a graphics canvas.
530/// Same action as Dump but in a graphical form.
531/// In addition pointers to other objects can be followed.
532///
533/// The following picture is the Inspect of a histogram object:
534/// \image html base_inspect.png
535
537{
538 gGuiFactory->CreateInspectorImp(this, 400, 200);
539}
540
541////////////////////////////////////////////////////////////////////////////////
542/// Returns kTRUE in case object contains browsable objects (like containers
543/// or lists of other objects).
544
546{
547 return kFALSE;
548}
549
550////////////////////////////////////////////////////////////////////////////////
551/// Default equal comparison (objects are equal if they have the same
552/// address in memory). More complicated classes might want to override
553/// this function.
554
556{
557 return obj == this;
558}
559
560////////////////////////////////////////////////////////////////////////////////
561/// The ls function lists the contents of a class on stdout. Ls output
562/// is typically much less verbose then Dump().
563
564void TObject::ls(Option_t *option) const
565{
567 std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : ";
568 std::cout << Int_t(TestBit(kCanDelete));
569 if (option && strstr(option,"noaddr")==nullptr) {
570 std::cout <<" at: "<< this ;
571 }
572 std::cout << std::endl;
573}
574
575////////////////////////////////////////////////////////////////////////////////
576/// This method must be overridden to handle object notification.
577
579{
580 return kFALSE;
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// This method must be overridden if a class wants to paint itself.
585/// The difference between Paint() and Draw() is that when a object
586/// draws itself it is added to the display list of the pad in
587/// which it is drawn (and automatically redrawn whenever the pad is
588/// redrawn). While paint just draws the object without adding it to
589/// the pad display list.
590
592{
593 // AbstractMethod("Paint");
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// Pop on object drawn in a pad to the top of the display list. I.e. it
598/// will be drawn last and on top of all other primitives.
599
601{
602 if (!gPad) return;
603
604 if (this == gPad->GetListOfPrimitives()->Last()) return;
605
606 TListIter next(gPad->GetListOfPrimitives());
607 TObject *obj;
608 while ((obj = next()))
609 if (obj == this) {
610 char *opt = StrDup(next.GetOption());
611 gPad->GetListOfPrimitives()->Remove((TObject*)this);
612 gPad->GetListOfPrimitives()->AddLast(this, opt);
613 gPad->Modified();
614 delete [] opt;
615 return;
616 }
617}
618
619////////////////////////////////////////////////////////////////////////////////
620/// This method must be overridden when a class wants to print itself.
621
623{
624 std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << std::endl;
625}
626
627////////////////////////////////////////////////////////////////////////////////
628/// Read contents of object with specified name from the current directory.
629/// First the key with the given name is searched in the current directory,
630/// next the key buffer is deserialized into the object.
631/// The object must have been created before via the default constructor.
632/// See TObject::Write().
633
635{
636 if (gDirectory) return gDirectory->ReadTObject(this,name);
637 else return 0;
638}
639
640////////////////////////////////////////////////////////////////////////////////
641/// Recursively remove this object from a list. Typically implemented
642/// by classes that can contain multiple references to a same object.
643
645{
646}
647
648
649////////////////////////////////////////////////////////////////////////////////
650/// Save this object in the file specified by filename.
651///
652/// - if "filename" contains ".root" the object is saved in filename as root
653/// binary file.
654///
655/// - if "filename" contains ".xml" the object is saved in filename as a xml
656/// ascii file.
657///
658/// - if "filename" contains ".cc" the object is saved in filename as C code
659/// independant from ROOT. The code is generated via SavePrimitive().
660/// Specific code should be implemented in each object to handle this
661/// option. Like in TF1::SavePrimitive().
662///
663/// - otherwise the object is written to filename as a CINT/C++ script. The
664/// C++ code to rebuild this object is generated via SavePrimitive(). The
665/// "option" parameter is passed to SavePrimitive. By default it is an empty
666/// string. It can be used to specify the Draw option in the code generated
667/// by SavePrimitive.
668///
669/// The function is available via the object context menu.
670
671void TObject::SaveAs(const char *filename, Option_t *option) const
672{
673 //==============Save object as a root file===================================
674 if (filename && strstr(filename,".root")) {
675 if (gDirectory) gDirectory->SaveObjectAs(this,filename,"");
676 return;
677 }
678
679 //==============Save object as a XML file====================================
680 if (filename && strstr(filename,".xml")) {
681 if (gDirectory) gDirectory->SaveObjectAs(this,filename,"");
682 return;
683 }
684
685 //==============Save object as a JSON file================================
686 if (filename && strstr(filename,".json")) {
687 if (gDirectory) gDirectory->SaveObjectAs(this,filename,option);
688 return;
689 }
690
691 //==============Save object as a C, ROOT independant, file===================
692 if (filename && strstr(filename,".cc")) {
693 TString fname;
694 if (filename && strlen(filename) > 0) {
695 fname = filename;
696 } else {
697 fname.Form("%s.cc", GetName());
698 }
699 std::ofstream out;
700 out.open(fname.Data(), std::ios::out);
701 if (!out.good ()) {
702 Error("SaveAs", "cannot open file: %s", fname.Data());
703 return;
704 }
705 ((TObject*)this)->SavePrimitive(out,"cc");
706 out.close();
707 Info("SaveAs", "cc file: %s has been generated", fname.Data());
708 return;
709 }
710
711 //==============Save as a C++ CINT file======================================
712 TString fname;
713 if (filename && strlen(filename) > 0) {
714 fname = filename;
715 } else {
716 fname.Form("%s.C", GetName());
717 }
718 std::ofstream out;
719 out.open(fname.Data(), std::ios::out);
720 if (!out.good ()) {
721 Error("SaveAs", "cannot open file: %s", fname.Data());
722 return;
723 }
724 out <<"{"<<std::endl;
725 out <<"//========= Macro generated from object: "<<GetName()<<"/"<<GetTitle()<<std::endl;
726 out <<"//========= by ROOT version"<<gROOT->GetVersion()<<std::endl;
727 ((TObject*)this)->SavePrimitive(out,option);
728 out <<"}"<<std::endl;
729 out.close();
730 Info("SaveAs", "C++ Macro file: %s has been generated", fname.Data());
731}
732
733////////////////////////////////////////////////////////////////////////////////
734/// Save a primitive as a C++ statement(s) on output stream "out".
735
736void TObject::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
737{
738 out << "//Primitive: " << GetName() << "/" << GetTitle()
739 <<". You must implement " << ClassName() << "::SavePrimitive" << std::endl;
740}
741
742////////////////////////////////////////////////////////////////////////////////
743/// Set drawing option for object. This option only affects
744/// the drawing style and is stored in the option field of the
745/// TObjOptLink supporting a TPad's primitive list (TList).
746/// Note that it does not make sense to call object.SetDrawOption(option)
747/// before having called object.Draw().
748
750{
751 if (!gPad || !option) return;
752
753 TListIter next(gPad->GetListOfPrimitives());
754 delete gPad->FindObject("Tframe");
755 TObject *obj;
756 while ((obj = next()))
757 if (obj == this) {
758 next.SetOption(option);
759 return;
760 }
761}
762
763////////////////////////////////////////////////////////////////////////////////
764/// Set or unset the user status bits as specified in f.
765
767{
768 if (set)
769 SetBit(f);
770 else
771 ResetBit(f);
772}
773
774////////////////////////////////////////////////////////////////////////////////
775/// Set the unique object id.
776
778{
779 fUniqueID = uid;
780}
781
782////////////////////////////////////////////////////////////////////////////////
783/// Set current style settings in this object
784/// This function is called when either TCanvas::UseCurrentStyle
785/// or TROOT::ForceStyle have been invoked.
786
788{
789}
790
791////////////////////////////////////////////////////////////////////////////////
792/// Write this object to the current directory.
793/// The data structure corresponding to this object is serialized.
794/// The corresponding buffer is written to the current directory
795/// with an associated key with name "name".
796///
797/// Writing an object to a file involves the following steps:
798///
799/// - Creation of a support TKey object in the current directory.
800/// The TKey object creates a TBuffer object.
801///
802/// - The TBuffer object is filled via the class::Streamer function.
803///
804/// - If the file is compressed (default) a second buffer is created to
805/// hold the compressed buffer.
806///
807/// - Reservation of the corresponding space in the file by looking
808/// in the TFree list of free blocks of the file.
809///
810/// - The buffer is written to the file.
811///
812/// Bufsize can be given to force a given buffer size to write this object.
813/// By default, the buffersize will be taken from the average buffer size
814/// of all objects written to the current file so far.
815///
816/// If a name is specified, it will be the name of the key.
817/// If name is not given, the name of the key will be the name as returned
818/// by GetName().
819///
820/// The option can be a combination of: kSingleKey, kOverwrite or kWriteDelete
821/// Using the kOverwrite option a previous key with the same name is
822/// overwritten. The previous key is deleted before writing the new object.
823/// Using the kWriteDelete option a previous key with the same name is
824/// deleted only after the new object has been written. This option
825/// is safer than kOverwrite but it is slower.
826/// NOTE: Neither kOverwrite nor kWriteDelete reduces the size of a TFile--
827/// the space is simply freed up to be overwritten; in the case of a TTree,
828/// it is more complicated. If one opens a TTree, appends some entries,
829/// then writes it out, the behaviour is effectively the same. If, however,
830/// one creates a new TTree and writes it out in this way,
831/// only the metadata is replaced, effectively making the old data invisible
832/// without deleting it. TTree::Delete() can be used to mark all disk space
833/// occupied by a TTree as free before overwriting its metadata this way.
834/// The kSingleKey option is only used by TCollection::Write() to write
835/// a container with a single key instead of each object in the container
836/// with its own key.
837///
838/// An object is read from the file into memory via TKey::Read() or
839/// via TObject::Read().
840///
841/// The function returns the total number of bytes written to the file.
842/// It returns 0 if the object cannot be written.
843
844Int_t TObject::Write(const char *name, Int_t option, Int_t bufsize) const
845{
846 if (R__unlikely(option & kOnlyPrepStep))
847 return 0;
848
849 TString opt = "";
850 if (option & kSingleKey) opt += "SingleKey";
851 if (option & kOverwrite) opt += "OverWrite";
852 if (option & kWriteDelete) opt += "WriteDelete";
853
854 if (gDirectory) return gDirectory->WriteTObject(this,name,opt.Data(),bufsize);
855 else {
856 const char *objname = "no name specified";
857 if (name) objname = name;
858 else objname = GetName();
859 Error("Write","The current directory (gDirectory) is null. The object (%s) has not been written.",objname);
860 return 0;
861 }
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Write this object to the current directory. For more see the
866/// const version of this method.
867
868Int_t TObject::Write(const char *name, Int_t option, Int_t bufsize)
869{
870 return ((const TObject*)this)->Write(name, option, bufsize);
871}
872
873////////////////////////////////////////////////////////////////////////////////
874/// Stream an object of class TObject.
875
876void TObject::Streamer(TBuffer &R__b)
877{
878 if (IsA()->CanIgnoreTObjectStreamer()) return;
879 UShort_t pidf;
880 if (R__b.IsReading()) {
881 R__b.SkipVersion(); // Version_t R__v = R__b.ReadVersion(); if (R__v) { }
882 R__b >> fUniqueID;
883 R__b >> fBits;
884 fBits |= kIsOnHeap; // by definition de-serialized object is on heap
885 if (TestBit(kIsReferenced)) {
886 //if the object is referenced, we must read its old address
887 //and store it in the ProcessID map in gROOT
888 R__b >> pidf;
889 pidf += R__b.GetPidOffset();
890 TProcessID *pid = R__b.ReadProcessID(pidf);
891 if (pid) {
892 UInt_t gpid = pid->GetUniqueID();
893 if (gpid>=0xff) {
894 fUniqueID = fUniqueID | 0xff000000;
895 } else {
896 fUniqueID = ( fUniqueID & 0xffffff) + (gpid<<24);
897 }
898 pid->PutObjectWithID(this);
899 }
900 }
901 } else {
902 R__b.WriteVersion(TObject::IsA());
903 if (!TestBit(kIsReferenced)) {
904 R__b << fUniqueID;
905 R__b << fBits;
906 } else {
907 //if the object is referenced, we must save its address/file_pid
908 UInt_t uid = fUniqueID & 0xffffff;
909 R__b << uid;
910 R__b << fBits;
912 //add uid to the TRefTable if there is one
914 if(table) table->Add(uid, pid);
915 pidf = R__b.WriteProcessID(pid);
916 R__b << pidf;
917 }
918 }
919}
920
921////////////////////////////////////////////////////////////////////////////////
922/// Interface to ErrorHandler (protected).
923
924void TObject::DoError(int level, const char *location, const char *fmt, va_list va) const
925{
926 const char *classname = "UnknownClass";
927 if (TROOT::Initialized())
928 classname = ClassName();
929
930 ::ErrorHandler(level, Form("%s::%s", classname, location), fmt, va);
931}
932
933////////////////////////////////////////////////////////////////////////////////
934/// Issue info message. Use "location" to specify the method where the
935/// warning occurred. Accepts standard printf formatting arguments.
936
937void TObject::Info(const char *location, const char *va_(fmt), ...) const
938{
939 va_list ap;
940 va_start(ap, va_(fmt));
941 DoError(kInfo, location, va_(fmt), ap);
942 va_end(ap);
943}
944
945////////////////////////////////////////////////////////////////////////////////
946/// Issue warning message. Use "location" to specify the method where the
947/// warning occurred. Accepts standard printf formatting arguments.
948
949void TObject::Warning(const char *location, const char *va_(fmt), ...) const
950{
951 va_list ap;
952 va_start(ap, va_(fmt));
953 DoError(kWarning, location, va_(fmt), ap);
954 va_end(ap);
955 if (TROOT::Initialized())
956 gROOT->Message(1001, this);
957}
958
959////////////////////////////////////////////////////////////////////////////////
960/// Issue error message. Use "location" to specify the method where the
961/// error occurred. Accepts standard printf formatting arguments.
962
963void TObject::Error(const char *location, const char *va_(fmt), ...) const
964{
965 va_list ap;
966 va_start(ap, va_(fmt));
967 DoError(kError, location, va_(fmt), ap);
968 va_end(ap);
969 if (TROOT::Initialized())
970 gROOT->Message(1002, this);
971}
972
973////////////////////////////////////////////////////////////////////////////////
974/// Issue system error message. Use "location" to specify the method where
975/// the system error occurred. Accepts standard printf formatting arguments.
976
977void TObject::SysError(const char *location, const char *va_(fmt), ...) const
978{
979 va_list ap;
980 va_start(ap, va_(fmt));
981 DoError(kSysError, location, va_(fmt), ap);
982 va_end(ap);
983 if (TROOT::Initialized())
984 gROOT->Message(1003, this);
985}
986
987////////////////////////////////////////////////////////////////////////////////
988/// Issue fatal error message. Use "location" to specify the method where the
989/// fatal error occurred. Accepts standard printf formatting arguments.
990
991void TObject::Fatal(const char *location, const char *va_(fmt), ...) const
992{
993 va_list ap;
994 va_start(ap, va_(fmt));
995 DoError(kFatal, location, va_(fmt), ap);
996 va_end(ap);
997 if (TROOT::Initialized())
998 gROOT->Message(1004, this);
999}
1000
1001////////////////////////////////////////////////////////////////////////////////
1002/// Use this method to implement an "abstract" method that you don't
1003/// want to leave purely abstract.
1004
1005void TObject::AbstractMethod(const char *method) const
1006{
1007 Warning(method, "this method must be overridden!");
1008}
1009
1010////////////////////////////////////////////////////////////////////////////////
1011/// Use this method to signal that a method (defined in a base class)
1012/// may not be called in a derived class (in principle against good
1013/// design since a child class should not provide less functionality
1014/// than its parent, however, sometimes it is necessary).
1015
1016void TObject::MayNotUse(const char *method) const
1017{
1018 Warning(method, "may not use this method");
1019}
1020
1021////////////////////////////////////////////////////////////////////////////////
1022/// Use this method to declare a method obsolete. Specify as of which version
1023/// the method is obsolete and as from which version it will be removed.
1024
1025void TObject::Obsolete(const char *method, const char *asOfVers, const char *removedFromVers) const
1026{
1027 const char *classname = "UnknownClass";
1028 if (TROOT::Initialized())
1029 classname = ClassName();
1030
1031 ::Obsolete(Form("%s::%s", classname, method), asOfVers, removedFromVers);
1032}
1033
1034////////////////////////////////////////////////////////////////////////////////
1035/// Get status of object stat flag.
1036
1038{
1039 return fgObjectStat;
1040}
1041////////////////////////////////////////////////////////////////////////////////
1042/// Turn on/off tracking of objects in the TObjectTable.
1043
1045{
1046 fgObjectStat = stat;
1047}
1048
1049////////////////////////////////////////////////////////////////////////////////
1050/// Return destructor only flag
1051
1053{
1054 return fgDtorOnly;
1055}
1056
1057////////////////////////////////////////////////////////////////////////////////
1058/// Set destructor only flag
1059
1061{
1062 fgDtorOnly = (Longptr_t) obj;
1063}
1064
1065////////////////////////////////////////////////////////////////////////////////
1066/// Operator delete
1067
1068void TObject::operator delete(void *ptr)
1069{
1070 if ((Longptr_t) ptr != fgDtorOnly)
1072 else
1073 fgDtorOnly = 0;
1074}
1075
1076////////////////////////////////////////////////////////////////////////////////
1077/// Operator delete []
1078
1079void TObject::operator delete[](void *ptr)
1080{
1081 if ((Longptr_t) ptr != fgDtorOnly)
1083 else
1084 fgDtorOnly = 0;
1085}
1086
1087#ifdef R__SIZEDDELETE
1088////////////////////////////////////////////////////////////////////////////////
1089/// Operator delete for sized deallocation.
1090
1091void TObject::operator delete(void *ptr, size_t size)
1092{
1093 if ((Longptr_t) ptr != fgDtorOnly)
1095 else
1096 fgDtorOnly = 0;
1097}
1098
1099////////////////////////////////////////////////////////////////////////////////
1100/// Operator delete [] for sized deallocation.
1101
1102void TObject::operator delete[](void *ptr, size_t size)
1103{
1104 if ((Longptr_t) ptr != fgDtorOnly)
1106 else
1107 fgDtorOnly = 0;
1108}
1109#endif
1110
1111////////////////////////////////////////////////////////////////////////////////
1112/// Print value overload
1113
1114std::string cling::printValue(TObject *val) {
1115 std::ostringstream strm;
1116 strm << "Name: " << val->GetName() << " Title: " << val->GetTitle();
1117 return strm.str();
1118}
1119
1120#ifdef R__PLACEMENTDELETE
1121////////////////////////////////////////////////////////////////////////////////
1122/// Only called by placement new when throwing an exception.
1123
1124void TObject::operator delete(void *ptr, void *vp)
1125{
1126 TStorage::ObjectDealloc(ptr, vp);
1127}
1128
1129////////////////////////////////////////////////////////////////////////////////
1130/// Only called by placement new[] when throwing an exception.
1131
1132void TObject::operator delete[](void *ptr, void *vp)
1133{
1134 TStorage::ObjectDealloc(ptr, vp);
1135}
1136#endif
#define R__unlikely(expr)
Definition RConfig.hxx:598
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
unsigned long ULong_t
Definition RtypesCore.h:55
bool Bool_t
Definition RtypesCore.h:63
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
#define gDirectory
Definition TDirectory.h:385
constexpr Int_t kError
Definition TError.h:46
void ErrorHandler(int level, const char *location, const char *fmt, std::va_list va)
General error handler function. It calls the user set error handler.
Definition TError.cxx:111
constexpr Int_t kFatal
Definition TError.h:49
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
constexpr Int_t kInfo
Definition TError.h:44
constexpr Int_t kSysError
Definition TError.h:48
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGuiFactory * gGuiFactory
Definition TGuiFactory.h:66
#define gInterpreter
R__EXTERN TObjectTable * gObjectTable
Int_t gDebug
Definition TROOT.cxx:592
#define gROOT
Definition TROOT.h:404
char * Form(const char *fmt,...)
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2515
#define gPad
#define va_(arg)
Definition Varargs.h:41
#define snprintf
Definition civetweb.c:1540
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual void SkipVersion(const TClass *cl=0)=0
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition TBuffer.cxx:344
virtual UShort_t WriteProcessID(TProcessID *pid)=0
Always return 0 (current processID).
Definition TBuffer.cxx:353
virtual UShort_t GetPidOffset() const =0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:80
static Int_t AutoBrowse(TObject *obj, TBrowser *browser)
Browse external object inherited from TObject.
Definition TClass.cxx:1964
virtual TInspectorImp * CreateInspectorImp(const TObject *obj, UInt_t width, UInt_t height)
Create a batch version of TInspectorImp.
Iterator of linked list.
Definition TList.h:191
void SetOption(Option_t *option)
Sets the object option stored in the list.
Definition TList.cxx:1151
Option_t * GetOption() const
Returns the object option stored in the list.
Definition TList.cxx:1142
virtual void Add(TObject *obj)
Definition TList.h:81
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
An array of TObjects.
Definition TObjArray.h:31
static void AddObj(TObject *obj)
Add an object to the global object table gObjectTable.
void RemoveQuietly(TObject *obj)
Remove an object from the object table.
Mother of all ROOT objects.
Definition TObject.h:41
void AbstractMethod(const char *method) const
Use this method to implement an "abstract" method that you don't want to leave purely abstract.
Definition TObject.cxx:1005
virtual Bool_t IsFolder() const
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
Definition TObject.cxx:545
virtual void Inspect() const
Dump contents of this object in a graphics canvas.
Definition TObject.cxx:536
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Computes distance from point (px,py) to the object.
Definition TObject.cxx:258
static void SetObjectStat(Bool_t stat)
Turn on/off tracking of objects in the TObjectTable.
Definition TObject.cxx:1044
virtual Bool_t Notify()
This method must be overridden to handle object notification.
Definition TObject.cxx:578
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TObject.cxx:868
virtual Bool_t IsEqual(const TObject *obj) const
Default equal comparison (objects are equal if they have the same address in memory).
Definition TObject.cxx:555
@ kOverwrite
overwrite existing object with same name
Definition TObject.h:92
@ kSingleKey
write collection with single key
Definition TObject.h:91
@ kWriteDelete
write object, then delete previous key with same name
Definition TObject.h:93
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:429
virtual void Browse(TBrowser *b)
Browse object. May be overridden for another default action.
Definition TObject.cxx:191
virtual void Dump() const
Dump contents of object on stdout.
Definition TObject.cxx:338
UInt_t fUniqueID
object unique identifier
Definition TObject.h:44
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual const char * GetIconName() const
Returns mime type name of object.
Definition TObject.cxx:439
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition TObject.cxx:644
virtual void DoError(int level, const char *location, const char *fmt, va_list va) const
Interface to ErrorHandler (protected).
Definition TObject.cxx:924
virtual Bool_t HandleTimer(TTimer *timer)
Execute action in response of a timer timing out.
Definition TObject.cxx:483
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TObject.cxx:216
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:447
@ kIsOnHeap
object is on heap
Definition TObject.h:81
UInt_t fBits
bit field status word
Definition TObject.h:45
static Longptr_t fgDtorOnly
object for which to call dtor only (i.e. no delete)
Definition TObject.h:47
virtual void Execute(const char *method, const char *params, Int_t *error=0)
Execute method on this object with the given parameter string, e.g.
Definition TObject.cxx:349
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition TObject.cxx:977
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:787
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition TObject.cxx:413
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
void MayNotUse(const char *method) const
Use this method to signal that a method (defined in a base class) may not be called in a derived clas...
Definition TObject.cxx:1016
virtual TObject * DrawClone(Option_t *option="") const
Draw a clone of this object in the current selected pad for instance with: gROOT->SetSelectedPad(gPad...
Definition TObject.cxx:291
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to an event at (px,py).
Definition TObject.cxx:383
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:393
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:177
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Returns string containing info about the object at position (px,py).
Definition TObject.cxx:458
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:736
@ kOnlyPrepStep
Used to request that the class specific implementation of TObject::Write just prepare the objects to ...
Definition TObject.h:106
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:671
virtual void Delete(Option_t *option="")
Delete this object.
Definition TObject.cxx:241
static Longptr_t GetDtorOnly()
Return destructor only flag.
Definition TObject.cxx:1052
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:515
static Bool_t GetObjectStat()
Get status of object stat flag.
Definition TObject.cxx:1037
virtual void Copy(TObject &object) const
Copy this to obj.
Definition TObject.cxx:133
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void SetDrawOption(Option_t *option="")
Set drawing option for object.
Definition TObject.cxx:749
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:991
static void SetDtorOnly(void *obj)
Set destructor only flag.
Definition TObject.cxx:1060
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:777
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:473
virtual void DrawClass() const
Draw class inheritance tree of the class to which this object belongs.
Definition TObject.cxx:282
virtual Int_t Compare(const TObject *obj) const
Compare abstract method.
Definition TObject.cxx:231
virtual ~TObject()
TObject destructor.
Definition TObject.cxx:151
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:267
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition TObject.cxx:591
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:622
virtual void Pop()
Pop on object drawn in a pad to the top of the display list.
Definition TObject.cxx:600
virtual ULong_t Hash() const
Return hash value for this object.
Definition TObject.cxx:505
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
Definition TObject.cxx:564
static Bool_t fgObjectStat
if true keep track of objects in TObjectTable
Definition TObject.h:48
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kIsReferenced
if object is referenced by a TRef or TRefArray
Definition TObject.h:65
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
virtual Int_t Read(const char *name)
Read contents of object with specified name from the current directory.
Definition TObject.cxx:634
static void AddToTObjectTable(TObject *)
Private helper function which will dispatch to TObjectTable::AddObj.
Definition TObject.cxx:168
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
void Obsolete(const char *method, const char *asOfVers, const char *removedFromVers) const
Use this method to declare a method obsolete.
Definition TObject.cxx:1025
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition TProcessID.h:74
void PutObjectWithID(TObject *obj, UInt_t uid=0)
stores the object at the uid th slot in the table of objects The object uniqued is set as well as its...
static TProcessID * GetProcessWithUID(const TObject *obj)
static function returning a pointer to TProcessID with its pid encoded in the highest byte of obj->Ge...
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition TROOT.cxx:2834
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2819
A TRefTable maintains the association between a referenced object and the parent object supporting th...
Definition TRefTable.h:35
static TRefTable * GetRefTable()
Static function returning the current TRefTable.
virtual Int_t Add(Int_t uid, TProcessID *context=0)
Add a new uid to the table.
Definition TRefTable.cxx:88
static void ObjectDealloc(void *vp)
Used to deallocate a TObject on the heap (via TObject::operator delete()).
Definition TStorage.cxx:359
Basic string class.
Definition TString.h:136
const char * Data() const
Definition TString.h:369
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition TString.cxx:662
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2314
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void Modified(Bool_t flag=1)=0
virtual TVirtualPad * GetSelectedPad() const =0
virtual TList * GetListOfPrimitives() const =0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual void Update()=0
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
bool DeleteChangesMemory()
Definition TObject.cxx:120
bool DeleteChangesMemoryImpl()
Definition TObject.cxx:69
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
void CallRecursiveRemoveIfNeeded(TObject &obj)
call RecursiveRemove for obj if gROOT is valid and obj.TestBit(kMustCleanup) is true.
Definition TROOT.h:393