]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/trains/Option.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / Option.C
1 /**
2  * @file   Option.C
3  * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4  * @date   Tue Oct 16 18:59:04 2012
5  * 
6  * @brief  
7  * 
8  * 
9  * @ingroup pwglf_forward_trains_util
10  */
11 #ifndef OPTION_C
12 #define OPTION_C
13 #include <TNamed.h>
14 #include <iomanip>
15 #ifndef __CINT__
16 # include <TString.h>
17 # include <TList.h>
18 # include <TObjArray.h>
19 # include <TObjString.h>
20 # include <TMath.h>
21 # include <iostream>
22 # include <iomanip>
23 # include <cstdarg>
24 # include <cstdio>
25 #else
26 class TString;
27 class TList;
28 class TObjArray;
29 #endif
30
31 /** 
32  * An option.  The value is stored as a string 
33  *
34  * @ingroup pwglf_forward_trains_util
35  */
36 struct Option /* : public TNamed */
37 {
38   /** 
39    * Constructor 
40    * 
41    * @param name           Name of option
42    * @param arg            Dummy argument (possibly null)
43    * @param description    Description
44    * @param value          Default value 
45    */
46   Option(const TString& name, 
47          const TString& arg, 
48          const TString& description,
49          const TString& value)
50     : fName(name), fDescription(description), 
51       fValue(value), fArg(arg), fIsSet(false)
52   {}
53   /** 
54    * Copy constructor 
55    * 
56    * @param other Object to copy from 
57    */
58   Option(const Option& other)
59     : fName(other.fName), 
60       fDescription(other.fDescription),
61       fValue(other.fValue), 
62       fArg(other.fArg), 
63       fIsSet(other.fIsSet)
64   {}
65   /** 
66    * Assignment operator 
67    * 
68    * @param other Object to assign from 
69    *
70    * @return Reference to this object
71    */
72   Option& operator=(const Option& other)
73   {
74     if (&other == this) return *this;
75     
76     fName        = other.fName;
77     fDescription = other.fDescription;
78     fValue       = other.fValue;
79     fArg         = other.fArg;
80     fIsSet       = other.fIsSet;
81     
82     return *this;
83   }
84   /** 
85    * Set the value 
86    * 
87    * @param val New value 
88    */
89   void Set(const TString& val) 
90   { 
91     if (HasArg()) {
92       fIsSet = true;
93       fValue = val;
94       // Info("Set", "Setting option %s with arg %s to %s", 
95       // fName.Data(), fArg.Data(), fValue.Data());
96       return;
97     }
98
99     // Info("Set", "Setting option %s with no arg", fName.Data());
100     // Allow flags to get =true, =1, =false, =0 values
101     if (!val.IsNull() && 
102         (val.EqualTo("false", TString::kIgnoreCase) || 
103          (val.IsDigit() && !val.Atoi()))) {
104       fIsSet = false;
105       fValue = "false";
106     }
107     else {
108       fIsSet = true;
109       fValue = "true";
110     }
111   }
112   /** 
113    * Set the value
114    */
115   void Set() 
116   { 
117     if (HasArg()) { 
118       Error("Option::Set", "Option %s needs an argument", fName.Data());
119       return;
120     }
121     Set("true");
122   }
123   /** 
124    * Reset the set flag
125    * 
126    */
127   void Reset() 
128   { 
129     fIsSet = false; 
130     if (!HasArg()) fValue = "false";
131   }
132   /**
133    * @return constant reference to value 
134    */
135   const TString& Get() const { return fValue; }
136   /**
137    * @return true if this option was set externally
138    */
139   Bool_t IsSet() const { return fIsSet; }
140   /**
141    * @return true if this option needs an argument
142    */
143   Bool_t HasArg() const { return !fArg.IsNull(); }
144   /**
145    * @return value as a boolean value
146    */
147   Bool_t AsBool() const { return fIsSet; }
148   /**
149    * @return value as an integer value
150    */
151   Int_t    AsInt() const { return fValue.Atoi(); }
152   /**
153    * @return value as a long integer value
154    */
155   Long64_t AsLong() const { return fValue.Atoll(); } 
156   /**
157    * @return value as a double precision value
158    */
159   Double_t AsDouble() const { return fValue.Atof(); } 
160   /**
161    * @return value as a C string
162    */
163   const char* AsString() const { return fValue.Data(); } 
164   /** 
165    * @return Width of the name 
166    */
167   Int_t NameWidth() const { return fName.IsNull() ? 0 : fName.Length(); }
168   /** 
169    * @return the width of the dummy argument
170    */
171   Int_t ArgWidth() const { return fArg.IsNull() ? 0 : fArg.Length(); }
172   /** 
173    * Show help 
174    * 
175    * @param o Output stream 
176    * @param w With of option plus argument 
177    */
178   void Help(std::ostream& o, Int_t w=-1) const
179   {
180     TString tmp(fName);
181     if (HasArg()) { 
182       tmp.Append("=");
183       tmp.Append(fArg);
184     }
185     if (w <= 0) w = NameWidth() + ArgWidth() + 1;
186     std::ios::fmtflags oldf = o.setf(std::ios::left);
187     o << std::setw(w) << tmp << "  " << fDescription << " [";
188     if (!HasArg()) o << (IsSet() ? "true" : "false");
189     else           o << fValue;
190     o << "]" << std::endl;
191     o.setf(oldf);
192   }
193   /** 
194    * Show the option
195    * 
196    * @param o Output stream
197    * @param w With of name 
198    */
199   void Show(std::ostream& o, Int_t w=-1) const 
200   {
201     if (w <= 0) w = NameWidth();
202     std::ios::fmtflags oldf = o.setf(std::ios::left);
203     o << std::setw(w) << fName << ": ";
204     if (!HasArg()) o << (IsSet() ? "true" : "false");
205     else           o << fValue;
206     o << std::endl;
207     o.setf(oldf);
208   }
209   /** 
210    * Store option and possible value 
211    * 
212    * @param o Output stream
213    * @param quote If true, quote output 
214    */
215   void Store(std::ostream& o, bool quote=true) const 
216   {
217     o << fName;
218     if (!HasArg()) return;
219     o << "=" << (quote ? "\"" : "") << fValue << (quote ? "\"" : "");
220   }
221   TString fName;        // Name 
222   TString fDescription; // Description
223   TString fValue;       // Value 
224   TString fArg;         // Argument dummy 
225   Bool_t  fIsSet;       // True if this option was set 
226   
227   // ClassDef(Option,1) // Option 
228 };
229
230 /** 
231  * A List of options 
232  */
233 struct OptionList 
234 {
235   // Linked list element
236   struct Link 
237   {
238     Link*   fPrev;
239     Link*   fNext;
240     Option* fThis;
241     Link() : fPrev(0), fNext(0), fThis(0) {}
242     Link(Link* next, Option* opt)
243       : fPrev(next ? next->fPrev : 0), // Set previous 
244         fNext(next), // Set next link
245         fThis(opt) // Set data
246     {
247       if (fPrev) fPrev->fNext = this; // Set forward link
248       if (fNext) fNext->fPrev = this; // Set previous link
249     }
250     ~Link() { 
251       if (fPrev) fPrev->fNext = fNext;
252       if (fNext) fNext->fPrev = fPrev;
253       delete fThis;
254     }
255     Link(const Link& o)
256       : fPrev(o.fPrev), 
257         fNext(o.fNext), 
258         fThis(o.fThis)
259     {
260     }
261     Link& operator=(const Link& o)
262     {
263       if (&o == this) return *this;
264       fPrev = o.fPrev;
265       fNext = o.fNext;
266       fThis = o.fThis;
267       return *this;
268     }   
269   };
270   /** 
271    * Constructor 
272    */
273   OptionList() : fList(0) { }
274   /** 
275    * Copy constructor 
276    *
277    * @param other Object to copy from 
278    */
279   OptionList(const OptionList& other) 
280     : fList(0)
281   { 
282     // fList.SetOwner(); 
283     // TIter next(&other.fList);
284     // Option* o = 0;
285     // while ((o = static_cast<Option*>(next()))) 
286     //   fList.Add(new Option(*o));
287     Copy(other);
288   }
289   /** 
290    * Destructor 
291    */
292   ~OptionList() { Delete(); }
293
294   /** 
295    * Remove all options 
296    */
297   void Delete()
298   { 
299     Link* cur = fList;
300     while (cur) {
301       Link* tmp = cur->fNext;
302       delete cur;
303       cur = tmp;
304       // Remove(cur->fThis->fName);
305       // cur = tmp;
306     }
307     fList = 0;
308   }
309   /** 
310    * Assignment operator 
311    *
312    * @param other  Object to assign from 
313    *
314    * @return reference to this 
315    */
316   OptionList& operator=(const OptionList& other) 
317   { 
318     if (&other == this) return *this;
319     Delete();
320     Copy(other);
321     
322     return *this; 
323   }
324   /** 
325    * Copy list from other object
326    * 
327    * @param other Object to copy from 
328    */
329   void Copy(const OptionList& other)
330   {
331     Delete();
332     const Link* ocur = other.fList;
333     Link*       cur  = fList;
334     Link*       prev = fList;
335     while (ocur) { 
336       cur        = new Link;
337       cur->fThis = new Option(*(ocur->fThis));
338       cur->fNext = 0;
339       cur->fPrev = prev;
340       if (fList == 0) fList = cur;
341       if (prev)       prev->fNext = cur;
342       prev = cur;
343       ocur = ocur->fNext;
344     }
345   }
346   void DebugLink(const Link* link) const
347   {
348     std::cout << "Link=" << link;
349     if (link) {
350       std::cout << " prev=" << link->fPrev 
351                 << " next=" << link->fNext
352                 << " obj=" << link->fThis;
353       if (link->fThis) 
354         std::cout << " name=" << link->fThis->fName;
355     }
356     std::cout <<std::endl;
357   }
358   /** 
359    * Find an optio by name 
360    * 
361    * @param name Name of option to find
362    * 
363    * @return Pointer to option or null
364    */
365   Option* Find(const TString& name) const
366   {
367     const Link* cur = fList;
368     // DebugLink(cur);
369     while (cur && cur->fThis) { 
370       if (name.EqualTo(cur->fThis->fName)) return cur->fThis;
371       cur = cur->fNext;
372     }
373     return 0;
374   }
375   /** 
376    * Add an option with argument 
377    * 
378    * @param name Name of option
379    * @param arg  Dummy argument
380    * @param desc Description
381    * @param val  Default value 
382    * 
383    * @return Newly added option 
384    */
385   Option* Add(const TString& name, 
386               const TString& arg, 
387               const TString& desc, 
388               const TString& val="")
389   {
390     Option* o = Find(name);
391     if (o) { 
392       Warning("OptionList::Add", "Option %s already registered", name.Data());
393       return o;
394     }
395     // Info("Add", "New option %s with arg %s (%s) and value %s",    
396     //   name.Data(), arg.Data(), desc.Data(), val.Data());
397     o = new Option(name, arg, desc, val);
398     Link*  cur  = fList;
399     if (!cur) { 
400       cur = new Link;
401       cur->fThis = o;
402       cur->fNext = 0;
403       cur->fPrev = 0;
404       fList      = cur;
405     }
406     else {
407       Link* n = 0;
408       Link* l = 0;
409       while (cur) { 
410         if (cur->fThis->fName.CompareTo(name) < 0) { 
411           l   = cur;
412           cur = cur->fNext;
413           continue;
414         }
415         n = new Link(cur, o);
416         if (cur == fList) fList = n;
417         break;
418       }
419       if (!n) { 
420         n = new Link;
421         l->fNext = n;
422         n->fPrev = l;
423         n->fNext = 0;
424         n->fThis = o;
425       }
426     }
427     return o;
428   }
429   /** 
430    * Add an option with no argument
431    * 
432    * @param name Name of option
433    * @param desc Description 
434    * 
435    * @return Newly created option 
436    */
437   Option* Add(const TString& name, 
438               const TString& desc)
439   {
440     return Add(name, "", desc, "");
441   }
442   /** 
443    * Add an option with no argument
444    * 
445    * @param name Name of option
446    * @param desc Description 
447    * @param def  Default value (true, or false)
448    * 
449    * @return Newly created option 
450    */
451   Option* Add(const TString& name, 
452               const TString& desc,
453               Bool_t         def)
454   {
455     Option* o = Add(name, "", desc, "");
456     if (o) o->Set(def ? "true" : "false");
457     return o;
458   }
459   /** 
460    * Add an option with argument 
461    * 
462    * @param name Name of option
463    * @param arg  Dummy argument
464    * @param desc Description
465    * @param val  Default value 
466    * @param asHex If true, interpret as hex number 
467    * 
468    * @return Newly added option 
469    */
470   Option* Add(const TString& name, 
471               const TString& arg, 
472               const TString& desc, 
473               Int_t          val, 
474               Bool_t         asHex=false)
475   {
476     if (asHex) {
477       UInt_t uval = val;
478       return Add(name, arg, desc, Form("0x%x", uval));
479     }
480     return Add(name, arg, desc, Form("%d", val));
481   }
482   /** 
483    * Add an option with argument 
484    * 
485    * @param name Name of option
486    * @param arg  Dummy argument
487    * @param desc Description
488    * @param val  Default value 
489    * @param asHex If true, interpret as hex 
490    * 
491    * @return Newly added option 
492    */
493   Option* Add(const TString& name, 
494               const TString& arg, 
495               const TString& desc, 
496               Long64_t       val, 
497               Bool_t         asHex=false)
498   {
499     if (asHex) {
500       ULong64_t uval = val;
501       return Add(name, arg, desc, Form("0x%llx", uval));
502     }
503     return Add(name, arg, desc, Form("%lld", val));
504   }
505   /** 
506    * Add an option with argument 
507    * 
508    * @param name Name of option
509    * @param arg  Dummy argument
510    * @param desc Description
511    * @param val  Default value 
512    * 
513    * @return Newly added option 
514    */
515   Option* Add(const TString& name, 
516               const TString& arg, 
517               const TString& desc, 
518               Double_t val)
519   {
520     return Add(name, arg, desc, Form("%lg", val));
521   }
522
523   /** 
524    * Remove an option 
525    * 
526    * @param name Name of option to remove 
527    */
528   void Remove(const TString& name)
529   {
530     Link* cur = fList;
531     while (cur) { 
532       if (!cur->fThis->fName.EqualTo(name)) {
533         cur = cur->fNext;
534         continue;
535       }
536       if (fList == cur) fList = cur->fNext;
537       delete cur;
538       break;
539     }
540   }
541   /** 
542    * Check if a given option was set externally
543    * 
544    * @param name Name of option
545    * 
546    * @return true if option exists and was set externally 
547    */
548   Bool_t Has(const TString& name) const
549   {
550     Option* o = Find(name);
551     return (o && o->IsSet());
552   }
553   /** 
554    * Get the value of an option
555    * 
556    * @param name Name of option
557    * 
558    * @return Value of option, or empty string 
559    */
560   const TString& Get(const TString& name) const
561   {
562     static TString null("");
563     Option* o = Find(name);
564     if (!o) return null;
565     return o->Get();
566   }
567   /** 
568    * Get a value using a format statement. Remember argument(s) must
569    * be passed by address (as pointers)
570    * 
571    * @param name Name of option @param format Format statement.
572    * Remeber, double and long needs the "l" modifier
573    * 
574    * @return true on success
575    */
576   Bool_t GetF(const TString& name, const Char_t* format, ...) const
577   {
578     Option* o = Find(name);
579     if (!o) return false;
580     
581     va_list ap;
582     va_start(ap, format);
583     int ret = vsscanf(o->fValue.Data(), format, ap);
584     va_end(ap);
585     
586     return ret > 0;
587   }
588   /** 
589    * Get value of an option as a boolean 
590    * 
591    * @param name Name of 
592    * 
593    * @return Value or false if not found
594    */
595   Bool_t AsBool(const TString& name) const 
596   {
597     Option* o = Find(name);
598     if (!o) return false;
599     return o->AsBool();
600   }
601   /** 
602    * Return value of an option as an integer
603    * 
604    * @param name Name of option 
605    * @param def  Default value if options isn't found 
606    * 
607    * @return Value or default value 
608    */
609   Int_t AsInt(const TString& name, Int_t def=0) const
610   {
611     Option* o = Find(name);
612     if (!o) return def;
613     return o->AsInt();
614   }
615   /** 
616    * Return value of an option as an integer
617    * 
618    * @param name Name of option 
619    * @param def  Default value if options isn't found 
620    * 
621    * @return Value or default value 
622    */
623   Long64_t AsLong(const TString& name, Long64_t def=0) const
624   {
625     Option* o = Find(name);
626     if (!o) return def;
627     return o->AsLong();
628   }
629   /** 
630    * Return value of an option as a double precision real number
631    * 
632    * @param name Name of option 
633    * @param def  Default value if options isn't found 
634    * 
635    * @return Value or default value 
636    */
637   Double_t AsDouble(const TString& name, Double_t def=0) const
638   {
639     Option* o = Find(name);
640     if (!o) return def;
641     return o->AsDouble();
642   }
643   /** 
644    * return value of an option as a string 
645    * 
646    * @param name Name of option
647    * @param def  Default valie if option isn't found 
648    * 
649    * @return Value or default value
650    */
651   const char* AsString(const TString& name, const TString& def="") const
652   {
653     Option* o = Find(name);
654     if (!o) return def.Data();
655     return o->AsString();
656   }
657   /** 
658    * return value of an option as a string 
659    * 
660    * @param name Name of option
661    * @param def  Default valie if option isn't found 
662    * 
663    * @return Value or default value
664    */
665   const TString& AsTString(const TString& name, const TString& def="") const
666   {
667     Option* o = Find(name);
668     if (!o) return def;
669     return o->Get();
670   }
671   /** 
672    * Set value using a format statement 
673    * 
674    * @param name   Name of option.
675    * @param format Format statement
676    */
677   void SetF(const TString& name, const Char_t* format, ...)
678   {
679     Option* o = Find(name);
680     if (!o) return;
681     
682     static char buf[1024];
683     va_list ap;
684     
685     va_start(ap, format);
686     vsnprintf(buf, 1023, format, ap);
687     buf[1023] = '\0';
688     va_end(ap);
689     
690     o->Set(buf);
691   }
692   /** 
693    * Set an option
694    * 
695    * @param name   Name of option
696    * @param value  Value of option
697    */
698   void Set(const TString& name, const TString& value)
699   {
700     Option* o = Find(name);
701     if (!o) return;
702     o->Set(value);
703   }
704   /** 
705    * Set a flag 
706    * 
707    * @param name Name of flag 
708    */
709   void Set(const TString& name)
710   {
711     Option* o = Find(name);
712     if (!o) return;
713     o->Set();
714   }   
715   /** 
716    * Set long integer value 
717    * 
718    * @param name Name of option
719    * @param val  Value 
720    * @param asHex If true, interpret as hex 
721    */
722   void Set(const TString& name, Int_t val, Bool_t asHex=false)
723   {
724     if (asHex) Set(name, Form("0x%x", val));
725     else       Set(name, Form("%d", val));
726   }
727   /** 
728    * Set long integer value 
729    * 
730    * @param name Name of option
731    * @param val  Value 
732    * @param asHex If true, interpret as hex value 
733    */
734   void Set(const TString& name, Long64_t val, Bool_t asHex=false)
735   {
736     ULong64_t uval = val;
737     if (asHex) Set(name, Form("0x%llx", uval));
738     else       Set(name, Form("%lld", val));
739   }
740   /** 
741    * Set double precision floating point value 
742    * 
743    * @param name Name of option
744    * @param val  Value 
745    */
746   void Set(const TString& name, Double_t val) 
747   {
748     Set(name, Form("%lg", val));
749   }
750   /** 
751    * Parse the options given in tmp 
752    * 
753    * @param tmp     String to pass
754    * @param delims  Delimiters 
755    * 
756    * @return true on success 
757    */
758   Bool_t Parse(const TString& tmp, const TString& delims)
759   {
760     TObjArray* opts = tmp.Tokenize(delims);
761     // Info("OptionList::Parse", "Parsing options %s", tmp.Data());
762     Bool_t ret = Parse(opts);
763     opts->Delete();
764     return ret;
765   }
766   /** 
767    * Parse options given in a collection 
768    * 
769    * @param opts List of arguments 
770    * @param ignoreUnknown If true, ignore unknown options 
771    * 
772    * @return true on success
773    */
774   Bool_t Parse(const TCollection* opts, Bool_t ignoreUnknown=false)
775   {
776     // Info("OptionList::Parse", "List of options");
777     // opts->ls();
778     TIter       next(opts);
779     TObjString* o = 0;
780     while ((o = static_cast<TObjString*>(next()))) { 
781       TString& s   = o->String();
782       TString  key = s;
783       TString  val = "";
784       Int_t    eq  = s.Index("=");
785       if (eq != kNPOS) {
786         key = s(0, eq);
787         val = s(eq+1, s.Length()-eq-1);
788       }
789
790       // Info("OptionList::Parse", "Looking for key=%s", key.Data());
791       Option*  opt = Find(key);
792       if (!opt) { 
793         if (!ignoreUnknown)
794           Warning("OptionList::Parse", "Unknown option: \"%s\"", s.Data());
795         continue;
796       }
797       if (opt->HasArg() && val.IsNull()) { 
798         Warning("OptionList::Parse", 
799                 "Option %s needs an argument, using default %s", 
800                 key.Data(), opt->fValue.Data());
801         val = opt->fValue;
802         // return false;
803       }
804       opt->Set(val);
805     }
806     return true;
807   }
808   /** 
809    * Find the widest name and dummy argument
810    * 
811    * @param nWidth On return, the largest width of option names 
812    * @param aWidth On return, the largest width of option dummy args
813    */
814   void Widest(Int_t& nWidth, Int_t& aWidth) const 
815   {
816     nWidth = 0;
817     aWidth = 0;
818     const Link* cur = fList;
819     while (cur) { 
820       Option* opt = cur->fThis;
821       nWidth = TMath::Max(nWidth, opt->NameWidth());
822       aWidth = TMath::Max(aWidth, opt->ArgWidth());
823       cur = cur->fNext;
824     }
825
826     // while ((opt = static_cast<Option*>(next()))) {
827     // }
828   }
829   /** 
830    * Display option help
831    * 
832    * @param o Output stream 
833    * @param prefix Prefix for each option.
834    */
835   void Help(std::ostream& o, const char* prefix="  ") const 
836   {
837     Int_t nWidth, aWidth;
838     Widest(nWidth, aWidth);
839     if (aWidth > 0) nWidth += aWidth+1;
840
841     const Link* cur = fList;
842     while (cur) { 
843       Option* opt = cur->fThis;
844       o << prefix;
845       opt->Help(o, nWidth);
846       cur = cur->fNext;
847     }
848   }
849   /** 
850    * Show the values of options 
851    * 
852    * @param o Output stream
853    * @param prefix Prefix for each option
854    */
855   void Show(std::ostream& o, const char* prefix="  ") const 
856   {
857     Int_t nWidth, aWidth;
858     Widest(nWidth, aWidth);
859
860
861     const Link* cur = fList;
862     while (cur) { 
863       Option* opt = cur->fThis;
864       o << prefix;
865       opt->Show(o, nWidth);
866       cur = cur->fNext;
867     }
868   }
869   /** 
870    * Show the values of options 
871    * 
872    * @param o Output stream
873    * @param prefix Prefix for each option
874    * @param delim Delimters 
875    * @param quote Quote output 
876    * @param onlySet if true, only output set options 
877    */
878   void Store(std::ostream& o, const char* prefix="", 
879              const char* delim=",", bool quote=true, 
880              bool onlySet=false) const 
881   {
882     Int_t nWidth, aWidth;
883     Widest(nWidth, aWidth);
884
885     const Link* cur = fList;
886     while (cur) { 
887       Option* opt = cur->fThis;
888       if ((!opt->HasArg() || onlySet) && !opt->IsSet()) {
889         cur = cur->fNext;
890         continue;
891       }
892       o << prefix;
893       opt->Store(o, quote);
894       o << delim;
895       cur = cur->fNext;
896     }
897   }
898   // Our linked list
899   Link* fList;
900
901   static void Test(const char* opts="")
902   {
903     OptionList l;
904     l.Add("int", "NUMBER", "Integer", "42");
905     l.Add("float", "NUMBER", "Floating point", "3.14");
906     l.Add("bool", "Flag");
907     l.Add("hex", "NUMBER", "Hexadecimal", "0xdead");
908     l.Add("string", "STRING", "A string", "Hello, world");
909     l.Show(std::cout, "\t");
910     
911     std::cout << "Find" << std::endl;
912     Option* b = l.Find("bool");
913     b->Set("true");
914     b->Show(std::cout);
915
916     std::cout << "SetF" << std::endl;
917     l.SetF("float", "%f", 2.17);
918     l.Show(std::cout, "\t");
919     
920     std::cout << "GetF" << std::endl;
921     Float_t f;
922     l.GetF("float", "%f", &f);
923     std::cout << "\tf=" << f << std::endl;
924     std::cout << "Remove" << std::endl;
925     l.Remove("float");
926     l.Show(std::cout, "\t");
927
928     std::cout << "Set" << std::endl;
929     l.Set("int", "10");
930     l.Set("hex", 0xbeef, true);
931     l.Set("bool", "false");
932     l.Show(std::cout, "\t");
933
934     std::cout << "Copy" << std::endl;
935     OptionList c(l);
936     c.Show(std::cout, "\t");
937
938     std::cout << "Parse" << std::endl;
939     c.Parse(opts,",");
940     c.Show(std::cout, "\t");
941     std::cout << "End of test" << std::endl;
942   }
943   // TList fList;
944 };
945
946 #endif
947