Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooCmdConfig.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17
18/**
19\file RooCmdConfig.cxx
20\class RooCmdConfig
21\ingroup Roofitcore
22
23Configurable parser for RooCmdArg named
24arguments. It maps the contents of named arguments named to integers,
25doubles, strings and TObjects that can be retrieved after processing
26a set of RooCmdArgs. The parser also has options to enforce syntax
27rules such as (conditionally) required arguments, mutually exclusive
28arguments and dependencies between arguments.
29**/
30
31#include <RooCmdConfig.h>
32#include <RooMsgService.h>
33
34#include <ROOT/StringUtils.hxx>
35
36#include <iostream>
37#include <set>
38
39namespace {
40
41template<class Collection>
42typename Collection::const_iterator findVar(Collection const& coll, const char * name) {
43 return std::find_if(coll.begin(), coll.end(), [name](auto const& v){ return v.name == name; });
44}
45
46}
47
48
49
50
51////////////////////////////////////////////////////////////////////////////////
52/// Constructor taking descriptive name of owner/user which
53/// is used as prefix for any warning or error messages
54/// generated by this parser
55
56RooCmdConfig::RooCmdConfig(RooStringView methodName) : _name(methodName)
57{
63}
64
65
66namespace {
67
68void cloneList(TList const& inList, TList & outList) {
69 outList.SetOwner(true);
70 for(auto * elem : inList) {
71 outList.Add(elem->Clone()) ;
72 }
73}
74
75} // namespace
76
77
78////////////////////////////////////////////////////////////////////////////////
79/// Copy constructor
80
82 : TObject(other),
83 _name(other._name),
84 _verbose(other._verbose),
85 _error(other._error),
86 _allowUndefined(other._allowUndefined),
87 _iList(other._iList),
88 _dList(other._dList),
89 _sList(other._sList),
90 _oList(other._oList),
91 _cList(other._cList)
92{
93 cloneList(other._rList, _rList); // Required cmd list
94 cloneList(other._fList, _fList); // Forbidden cmd list
95 cloneList(other._mList, _mList); // Mutex cmd list
96 cloneList(other._yList, _yList); // Dependency cmd list
97 cloneList(other._pList, _pList); // Processed cmd list
98}
99
100
101
102////////////////////////////////////////////////////////////////////////////////
103/// Return string with names of arguments that were required, but not
104/// processed
105
106std::string RooCmdConfig::missingArgs() const
107{
108 std::string ret;
109
110 bool first = true;
111 for(TObject * s : _rList) {
112 if (first) {
113 first=false ;
114 } else {
115 ret += ", ";
116 }
117 ret += static_cast<TObjString*>(s)->String();
118 }
119
120 return ret;
121}
122
123
124
125////////////////////////////////////////////////////////////////////////////////
126/// Define that processing argument name refArgName requires processing
127/// of argument named neededArgName to successfully complete parsing
128
133
134
135
136////////////////////////////////////////////////////////////////////////////////
137/// Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName
138/// Define default value for this int property to be defVal in case named argument is not processed
139
140bool RooCmdConfig::defineInt(const char* name, const char* argName, int intNum, int defVal)
141{
142 if (findVar(_iList, name) != _iList.end()) {
143 coutE(InputArguments) << "RooCmdConfig::defineInt: name '" << name << "' already defined" << std::endl ;
144 return true ;
145 }
146
147 _iList.emplace_back();
148 auto& ri = _iList.back();
149 ri.name = name;
150 ri.argName = argName;
151 ri.val = defVal;
152 ri.num = intNum;
153 return false ;
154}
155
156
157
158////////////////////////////////////////////////////////////////////////////////
159/// Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argName
160/// Define default value for this double property to be defVal in case named argument is not processed
161
162bool RooCmdConfig::defineDouble(const char* name, const char* argName, int doubleNum, double defVal)
163{
164 if (findVar(_dList, name) != _dList.end()) {
165 coutE(InputArguments) << "RooCmdConfig::defineDouble: name '" << name << "' already defined" << std::endl ;
166 return true ;
167 }
168
169 _dList.emplace_back();
170 auto& rd = _dList.back();
171 rd.name = name;
172 rd.argName = argName;
173 rd.val = defVal;
174 rd.num = doubleNum;
175 return false ;
176}
177
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argName
182/// Define default value for this double property to be defVal in case named argument is not processed
183/// If appendMode is true, values found in multiple matching RooCmdArg arguments will be concatenated
184/// in the output string. If it is false, only the value of the last processed instance is retained
185
186bool RooCmdConfig::defineString(const char* name, const char* argName, int stringNum, const char* defVal, bool appendMode)
187{
188 if (findVar(_sList, name) != _sList.end()) {
189 coutE(InputArguments) << "RooCmdConfig::defineString: name '" << name << "' already defined" << std::endl ;
190 return true ;
191 }
192
193 _sList.emplace_back();
194 auto& rs = _sList.back();
195 rs.name = name;
196 rs.argName = argName;
197 rs.val = defVal;
198 rs.appendMode = appendMode;
199 rs.num = stringNum;
200 return false ;
201}
202
203
204
205////////////////////////////////////////////////////////////////////////////////
206/// Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName
207/// Define default value for this TObject property to be defVal in case named argument is not processed.
208/// If isArray is true, an array of TObjects is harvested in case multiple matching named arguments are processed.
209/// If isArray is false, only the TObject in the last processed named argument is retained
210
211bool RooCmdConfig::defineObject(const char* name, const char* argName, int setNum, const TObject* defVal, bool isArray)
212{
213
214 if (findVar(_oList, name) != _oList.end()) {
215 coutE(InputArguments) << "RooCmdConfig::defineObject: name '" << name << "' already defined" << std::endl ;
216 return true ;
217 }
218
219 _oList.emplace_back();
220 auto& os = _oList.back();
221 os.name = name;
222 os.argName = argName;
223 os.val.Add(const_cast<TObject*>(defVal));
224 os.appendMode = isArray;
225 os.num = setNum;
226 return false ;
227}
228
229
230
231////////////////////////////////////////////////////////////////////////////////
232/// Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName
233/// Define default value for this TObject property to be defVal in case named argument is not processed.
234/// If isArray is true, an array of TObjects is harvested in case multiple matching named arguments are processed.
235/// If isArray is false, only the TObject in the last processed named argument is retained
236
237bool RooCmdConfig::defineSet(const char* name, const char* argName, int setNum, const RooArgSet* defVal)
238{
239
240 if (findVar(_cList, name) != _cList.end()) {
241 coutE(InputArguments) << "RooCmdConfig::defineObject: name '" << name << "' already defined" << std::endl ;
242 return true ;
243 }
244
245 _cList.emplace_back();
246 auto& cs = _cList.back();
247 cs.name = name;
248 cs.argName = argName;
249 cs.val = const_cast<RooArgSet*>(defVal);
250 cs.num = setNum;
251 return false ;
252}
253
254
255
256////////////////////////////////////////////////////////////////////////////////
257/// Print configuration of parser
258
260{
261 // Find registered integer fields for this opcode
262 for(auto const& ri : _iList) {
263 std::cout << ri.name << "[int] = " << ri.val << std::endl ;
264 }
265
266 // Find registered double fields for this opcode
267 for(auto const& rd : _dList) {
268 std::cout << rd.name << "[double] = " << rd.val << std::endl ;
269 }
270
271 // Find registered string fields for this opcode
272 for(auto const& rs : _sList) {
273 std::cout << rs.name << "[string] = \"" << rs.val << "\"" << std::endl ;
274 }
275
276 // Find registered argset fields for this opcode
277 for(auto const& ro : _oList) {
278 std::cout << ro.name << "[TObject] = " ;
279 auto const * obj = ro.val.At(0);
280 if (obj) {
281 std::cout << obj->GetName() << std::endl ;
282 } else {
283
284 std::cout << "(null)" << std::endl ;
285 }
286 }
287}
288
289////////////////////////////////////////////////////////////////////////////////
290/// Process given list with RooCmdArgs
291/// Emit warning if duplicate arguments
292
294{
295 bool ret(false);
296 std::set<std::string> opcodes;
297 for (auto *arg : static_range_cast<RooCmdArg *>(argList)) {
298 auto opc = arg->opcode();
299 if (opc && opcodes.find(opc) != opcodes.end()) {
300 coutW(InputArguments) << _name << " WARNING: argument " << opc << " is duplicated" << std::endl;
301 } else if (opc) {
302 opcodes.insert(opc);
303 }
304 ret |= process(*arg);
305 }
306 return ret;
307}
308
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Process given RooCmdArg
313
315{
316 // Retrieve command code
317 const char* opc = arg.opcode() ;
318
319 // Ignore empty commands
320 if (!opc) return false ;
321
322 // Check if not forbidden
323 if (_fList.FindObject(opc)) {
324 coutE(InputArguments) << _name << " ERROR: argument " << opc << " not allowed in this context" << std::endl ;
325 _error = true ;
326 return true ;
327 }
328
329 // Check if this code generates any dependencies
331 if (dep) {
332 // Dependent command found, add to required list if not already processed
333 if (!_pList.FindObject(dep->GetTitle())) {
334 _rList.Add(new TObjString(dep->GetTitle())) ;
335 if (_verbose) {
336 std::cout << "RooCmdConfig::process: " << opc << " has unprocessed dependent " << dep->GetTitle()
337 << ", adding to required list" << std::endl ;
338 }
339 } else {
340 if (_verbose) {
341 std::cout << "RooCmdConfig::process: " << opc << " dependent " << dep->GetTitle() << " is already processed" << std::endl ;
342 }
343 }
344 }
345
346 // Check for mutexes
347 TObject * mutex = _mList.FindObject(opc) ;
348 if (mutex) {
349 if (_verbose) {
350 std::cout << "RooCmdConfig::process: " << opc << " excludes " << mutex->GetTitle()
351 << ", adding to forbidden list" << std::endl ;
352 }
353 _fList.Add(new TObjString(mutex->GetTitle())) ;
354 }
355
356
357 bool anyField(false) ;
358
359 // Find registered integer fields for this opcode
360 for(auto& ri : _iList) {
361 if (!TString(opc).CompareTo(ri.argName)) {
362 ri.val = arg.getInt(ri.num) ;
363 anyField = true ;
364 if (_verbose) {
365 std::cout << "RooCmdConfig::process " << ri.name << "[int]" << " set to " << ri.val << std::endl ;
366 }
367 }
368 }
369
370 // Find registered double fields for this opcode
371 for(auto& rd : _dList) {
372 if (!TString(opc).CompareTo(rd.argName)) {
373 rd.val = arg.getDouble(rd.num) ;
374 anyField = true ;
375 if (_verbose) {
376 std::cout << "RooCmdConfig::process " << rd.name << "[double]" << " set to " << rd.val << std::endl ;
377 }
378 }
379 }
380
381 // Find registered string fields for this opcode
382 for(auto& rs : _sList) {
383 if (rs.argName == opc) {
384
385 // RooCmdArg::getString can return nullptr, so we have to protect against this
386 auto const * newStr = arg.getString(rs.num);
387
388 if (!rs.val.empty() && rs.appendMode) {
389 rs.val += ",";
390 rs.val += newStr ? newStr : "(null)";
391 } else {
392 if(newStr) rs.val = newStr;
393 }
394 anyField = true ;
395 if (_verbose) {
396 std::cout << "RooCmdConfig::process " << rs.name << "[string]" << " set to " << rs.val << std::endl ;
397 }
398 }
399 }
400
401 // Find registered TObject fields for this opcode
402 for(auto& os : _oList) {
403 if (!TString(opc).CompareTo(os.argName)) {
404 if(!os.appendMode) os.val.Clear();
405 os.val.Add(const_cast<TObject*>(arg.getObject(os.num)));
406 anyField = true ;
407 if (_verbose) {
408 std::cout << "RooCmdConfig::process " << os.name << "[TObject]" << " set to " ;
409 if (os.val.At(0)) {
410 std::cout << os.val.At(0)->GetName() << std::endl ;
411 } else {
412 std::cout << "(null)" << std::endl ;
413 }
414 }
415 }
416 }
417
418 // Find registered RooArgSet fields for this opcode
419 for(auto& cs : _cList) {
420 if (!TString(opc).CompareTo(cs.argName)) {
421 cs.val = const_cast<RooArgSet*>(arg.getSet(cs.num));
422 anyField = true ;
423 if (_verbose) {
424 std::cout << "RooCmdConfig::process " << cs.name << "[RooArgSet]" << " set to " ;
425 if (cs.val) {
426 std::cout << cs.val->GetName() << std::endl ;
427 } else {
428 std::cout << "(null)" << std::endl ;
429 }
430 }
431 }
432 }
433
434 bool multiArg = !TString("MultiArg").CompareTo(opc) ;
435
436 if (!anyField && !_allowUndefined && !multiArg) {
437 coutE(InputArguments) << _name << " ERROR: unrecognized command: " << opc << std::endl ;
438 }
439
440
441 // Remove command from required-args list (if it was there)
442 TObject* obj;
443 while ( (obj = _rList.FindObject(opc)) ) {
444 _rList.Remove(obj);
445 }
446
447 // Add command the processed list
448 TNamed *pcmd = new TNamed(opc,opc) ;
449 _pList.Add(pcmd) ;
450
451 bool depRet = false ;
452 if (arg.procSubArgs()) {
453 for (int ia=0 ; ia<arg.subArgs().GetSize() ; ia++) {
454 RooCmdArg* subArg = static_cast<RooCmdArg*>(arg.subArgs().At(ia)) ;
455 if (strlen(subArg->GetName())>0) {
457 if (arg.prefixSubArgs()) {
458 subArgCopy.SetName(Form("%s::%s",arg.GetName(),subArg->GetName())) ;
459 }
461 }
462 }
463 }
464
465 return ((anyField||_allowUndefined)?false:true)||depRet ;
466}
467
468
469
470////////////////////////////////////////////////////////////////////////////////
471/// Return true if RooCmdArg with name 'cmdName' has been processed
472
473bool RooCmdConfig::hasProcessed(const char* cmdName) const
474{
475 return _pList.FindObject(cmdName) ? true : false ;
476}
477
478
479
480////////////////////////////////////////////////////////////////////////////////
481/// Return integer property registered with name 'name'. If no
482/// property is registered, return defVal
483
484int RooCmdConfig::getInt(const char* name, int defVal) const
485{
486 auto found = findVar(_iList, name);
487 return found != _iList.end() ? found->val : defVal;
488}
489
490
491
492////////////////////////////////////////////////////////////////////////////////
493/// Return double property registered with name 'name'. If no
494/// property is registered, return defVal
495
496double RooCmdConfig::getDouble(const char* name, double defVal) const
497{
498 auto found = findVar(_dList, name);
499 return found != _dList.end() ? found->val : defVal;
500}
501
502
503
504////////////////////////////////////////////////////////////////////////////////
505/// Return string property registered with name 'name'. If no
506/// property is registered, return defVal. If convEmptyToNull
507/// is true, empty string will be returned as null pointers
508
509const char* RooCmdConfig::getString(const char* name, const char* defVal, bool convEmptyToNull) const
510{
511 auto found = findVar(_sList, name);
512 if(found == _sList.end()) return defVal;
513 return (convEmptyToNull && found->val.empty()) ? nullptr : found->val.c_str();
514}
515
516
517
518////////////////////////////////////////////////////////////////////////////////
519/// Return TObject property registered with name 'name'. If no
520/// property is registered, return defVal
521
523{
524 auto found = findVar(_oList, name);
525 return found != _oList.end() ? found->val.At(0) : defVal ;
526}
527
528
529////////////////////////////////////////////////////////////////////////////////
530/// Return RooArgSet property registered with name 'name'. If no
531/// property is registered, return defVal
532
534{
535 auto found = findVar(_cList, name);
536 return found != _cList.end() ? found->val : defVal ;
537}
538
539
540
541////////////////////////////////////////////////////////////////////////////////
542/// Return list of objects registered with name 'name'
543
545{
546 const static RooLinkedList defaultDummy ;
547 auto found = findVar(_oList, name);
548 return found != _oList.end() ? found->val : defaultDummy ;
549}
550
551
552
553////////////////////////////////////////////////////////////////////////////////
554/// Return true of parsing was successful
555
556bool RooCmdConfig::ok(bool verbose) const
557{
558 if (_rList.GetSize()==0 && !_error) return true ;
559
560 if (verbose) {
561 std::string margs = missingArgs() ;
562 if (!margs.empty()) {
563 coutE(InputArguments) << _name << " ERROR: missing arguments: " << margs << std::endl ;
564 } else {
565 coutE(InputArguments) << _name << " ERROR: illegal combination of arguments and/or missing arguments" << std::endl ;
566 }
567 }
568 return false ;
569}
570
571
572
573////////////////////////////////////////////////////////////////////////////////
574/// Utility function that strips command names listed (comma separated) in cmdsToPurge from cmdList
575
577{
578 // Sanity check
579 if (!cmdsToPurge) return ;
580
581 // Copy command list for parsing
582 for(auto const& name : ROOT::Split(cmdsToPurge, ",")) {
583 if (TObject* cmd = cmdList.FindObject(name.c_str())) {
584 cmdList.Remove(cmd);
585 }
586 }
587
588}
589
590
591
592////////////////////////////////////////////////////////////////////////////////
593/// Utility function to filter commands listed in cmdNameList from cmdInList. Filtered arguments are put in the returned list.
594/// If removeFromInList is true then these commands are removed from the input list
595
597{
599 if (!cmdNameList) return filterList ;
600
601 // Copy command list for parsing
602 for(auto const& name : ROOT::Split(cmdNameList, ",")) {
603 if (TObject* cmd = cmdInList.FindObject(name.c_str())) {
604 if (removeFromInList) {
605 cmdInList.Remove(cmd) ;
606 }
607 filterList.Add(cmd) ;
608 }
609 }
610 return filterList ;
611}
612
613
614
615////////////////////////////////////////////////////////////////////////////////
616/// Find a given double in a list of RooCmdArg.
617/// Should only be used to initialise base classes in constructors.
618double RooCmdConfig::decodeDoubleOnTheFly(const char* callerID, const char* cmdArgName, int idx, double defVal,
619 std::initializer_list<std::reference_wrapper<const RooCmdArg>> args) {
621 pc.allowUndefined();
622 pc.defineDouble("theDouble", cmdArgName, idx, defVal);
623 pc.process(args.begin(), args.end());
624 return pc.getDouble("theDouble");
625}
#define coutW(a)
#define coutE(a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
const_iterator begin() const
const_iterator end() const
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
const RooArgSet * getSet(Int_t idx) const
Return RooArgSet stored in slot idx.
double getDouble(Int_t idx) const
Return double stored in slot idx.
Definition RooCmdArg.h:92
RooLinkedList const & subArgs() const
Return list of sub-arguments in this RooCmdArg.
Definition RooCmdArg.h:53
Int_t getInt(Int_t idx) const
Definition RooCmdArg.h:87
bool procSubArgs() const
Definition RooCmdArg.h:108
bool prefixSubArgs() const
Definition RooCmdArg.h:109
const char * opcode() const
Definition RooCmdArg.h:68
const char * getString(Int_t idx) const
Return string stored in slot idx.
Definition RooCmdArg.h:96
const TObject * getObject(Int_t idx) const
Return TObject stored in slot idx.
Definition RooCmdArg.h:100
Configurable parser for RooCmdArg named arguments.
std::vector< Var< RooArgSet * > > _cList
RooArgSet list.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
TList _pList
Processed cmd list.
bool hasProcessed(const char *cmdName) const
Return true if RooCmdArg with name 'cmdName' has been processed.
std::vector< Var< RooLinkedList > > _oList
Object list.
std::vector< Var< int > > _iList
Integer list.
std::vector< Var< double > > _dList
Double list.
double getDouble(const char *name, double defaultValue=0.0) const
Return double property registered with name 'name'.
void print() const
Print configuration of parser.
void defineDependency(const char *refArgName, const char *neededArgName)
Define that processing argument name refArgName requires processing of argument named neededArgName t...
bool defineDouble(const char *name, const char *argName, int doubleNum, double defValue=0.0)
Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argNam...
static void stripCmdList(RooLinkedList &cmdList, const char *cmdsToPurge)
Utility function that strips command names listed (comma separated) in cmdsToPurge from cmdList.
std::string _name
RooArgSet * getSet(const char *name, RooArgSet *set=nullptr) const
Return RooArgSet property registered with name 'name'.
bool defineSet(const char *name, const char *argName, int setNum, const RooArgSet *set=nullptr)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
std::vector< Var< std::string > > _sList
String list.
TList _yList
Dependency cmd list.
TList _fList
Forbidden cmd list.
bool ok(bool verbose) const
Return true of parsing was successful.
bool defineObject(const char *name, const char *argName, int setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false) const
Return string property registered with name 'name'.
bool defineString(const char *name, const char *argName, int stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
static double decodeDoubleOnTheFly(const char *callerID, const char *cmdArgName, int idx, double defVal, std::initializer_list< std::reference_wrapper< const RooCmdArg > > args)
Find a given double in a list of RooCmdArg.
const RooLinkedList & getObjectList(const char *name) const
Return list of objects registered with name 'name'.
TList _mList
Mutex cmd list.
bool defineInt(const char *name, const char *argName, int intNum, int defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
void allowUndefined(bool flag=true)
If flag is true the processing of unrecognized RooCmdArgs is not considered an error.
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
RooCmdConfig(RooStringView methodName)
Constructor taking descriptive name of owner/user which is used as prefix for any warning or error me...
RooLinkedList filterCmdList(RooLinkedList &cmdInList, const char *cmdNameList, bool removeFromInList=true) const
Utility function to filter commands listed in cmdNameList from cmdInList.
std::string missingArgs() const
Return string with names of arguments that were required, but not processed.
TObject * getObject(const char *name, TObject *obj=nullptr) const
Return TObject property registered with name 'name'.
TList _rList
Required cmd list.
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
TObject * At(int index) const
Return object stored in sequential position given by index.
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
A doubly linked list.
Definition TList.h:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:575
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:819
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:501
Basic string class.
Definition TString.h:138
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:464
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.