Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TParameter.h
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Maarten Ballintijn 21/06/2004
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 #ifndef ROOT_TParameter
13 #define ROOT_TParameter
14 
15 
16 //////////////////////////////////////////////////////////////////////////
17 // //
18 // TParameter<AParamType> //
19 // //
20 // Named parameter, streamable and storable. //
21 // //
22 //////////////////////////////////////////////////////////////////////////
23 
24 #include "Riostream.h"
25 
26 #include "TClass.h"
27 
28 #include "TObject.h"
29 
30 #include "TCollection.h"
31 
32 #include "TString.h"
33 
34 #include "TROOT.h"
35 
36 template <class AParamType>
37 class TParameter : public TObject {
38 
39 public:
40  // Defines options / status while merging:
41  enum EStatusBits { kMultiply = BIT(16), // Use multiplication
42  kMax = BIT(17), // Take max value
43  kMin = BIT(18), // Take min value
44  kFirst = BIT(19), // Take the first value
45  kLast = BIT(20), // Take the last value
46  kIsConst = BIT(21) // Set if all values are equal
47  };
48 
49 private:
50  TString fName;
51  AParamType fVal;
52 
53  void Reset() { ResetBit(kMultiply); ResetBit(kMax); ResetBit(kMin);
54  ResetBit(kFirst); ResetBit(kLast); }
55 
56 public:
57  TParameter(): fVal() { Reset(); SetBit(kIsConst); }
58  TParameter(const char *name, const AParamType &val)
59  : fName(name), fVal(val) { Reset(); SetBit(kIsConst);}
60  TParameter(const char *name, const AParamType &val, char mergemode)
61  : fName(name), fVal(val) { SetMergeMode(mergemode); SetBit(kIsConst);}
62  virtual ~TParameter()
63  {
64  // Required since we overload TObject::Hash.
65  ROOT::CallRecursiveRemoveIfNeeded(*this);
66  }
67 
68  const char *GetName() const { return fName; }
69  const AParamType &GetVal() const { return fVal; }
70  Bool_t IsConst() const { return (TestBit(kIsConst) ? kTRUE : kFALSE); }
71  void SetVal(const AParamType &val) { fVal = val; }
72 
73  // Merging modes:
74  // '+' addition ('OR' for booleans) [default]
75  // '*' multiplication ('AND' for booleans)
76  // 'M' maximum ('OR' for booleans)
77  // 'm' minimum ('AND' for booleans)
78  // 'f' first value
79  // 'l' last value
80  void SetMergeMode(char mergemode = '+') {
81  Reset();
82  if (mergemode == '*') {
83  SetBit(kMultiply);
84  } else if (mergemode == 'M') {
85  SetBit(kMax);
86  } else if (mergemode == 'm') {
87  SetBit(kMin);
88  } else if (mergemode == 'f') {
89  SetBit(kFirst);
90  } else if (mergemode == 'l') {
91  SetBit(kLast);
92  }
93  }
94  virtual ULong_t Hash() const { return fName.Hash(); }
95  virtual Bool_t IsSortable() const { return kTRUE; }
96  virtual Int_t Compare(const TObject *obj) const {
97  // Compare two TParameter objects. Returns 0 when equal, -1 when this is
98  // smaller and +1 when bigger (like strcmp).
99 
100  if (this == obj) return 0;
101  return fName.CompareTo(obj->GetName());
102  }
103 
104  virtual void ls(Option_t *) const {
105  // Print this parameter content
106  TROOT::IndentLevel();
107  std::cout << "OBJ: " << IsA()->GetName() << "\t" << fName << " = " << fVal << std::endl;
108  }
109 
110  virtual void Print(Option_t *) const {
111  // Print this parameter content
112  TROOT::IndentLevel();
113  std::cout << IsA()->GetName() << "\t" << fName << " = " << fVal << std::endl;
114  }
115 
116  virtual Int_t Merge(TCollection *in);
117 
118  ClassDef(TParameter,2) //Named templated parameter type
119 };
120 
121 template <class AParamType>
122 inline Int_t TParameter<AParamType>::Merge(TCollection *in) {
123  // Merge objects in the list.
124  // Returns the number of objects that were in the list.
125  TIter nxo(in);
126  Int_t n = 0;
127  while (TObject *o = nxo()) {
128  TParameter<AParamType> *c = dynamic_cast<TParameter<AParamType> *>(o);
129  if (c) {
130  // Check if constant
131  if (fVal != c->GetVal()) ResetBit(kIsConst);
132  if (TestBit(kMultiply)) {
133  // Multiply
134  fVal *= c->GetVal();
135  } else if (TestBit(kMax)) {
136  // Take max
137  if (c->GetVal() > fVal) fVal = c->GetVal();
138  } else if (TestBit(kMin)) {
139  // Take min
140  if (c->GetVal() < fVal) fVal = c->GetVal();
141  } else if (TestBit(kLast)) {
142  // Take the last
143  fVal = c->GetVal();
144  } else if (!TestBit(kFirst)) {
145  // Add, if not asked to take the first
146  fVal += c->GetVal();
147  }
148  n++;
149  }
150  }
151 
152  return n;
153 }
154 
155 // Specialization of Merge for Bool_t
156 template <>
157 inline Int_t TParameter<Bool_t>::Merge(TCollection *in)
158 {
159  // Merge bool objects in the list.
160  // Returns the number of objects that were in the list.
161  TIter nxo(in);
162  Int_t n = 0;
163  while (TObject *o = nxo()) {
164  TParameter<Bool_t> *c = dynamic_cast<TParameter<Bool_t> *>(o);
165  if (c) {
166  // Check if constant
167  if (fVal != (Bool_t) c->GetVal()) ResetBit(kIsConst);
168  if (TestBit(TParameter::kMultiply) || TestBit(kMin)) {
169  // And
170  fVal &= (Bool_t) c->GetVal();
171  } else if (TestBit(kLast)) {
172  // Take the last
173  fVal = (Bool_t) c->GetVal();
174  } else if (!TestBit(kFirst) || TestBit(kMax)) {
175  // Or
176  fVal |= (Bool_t) c->GetVal();
177  }
178  n++;
179  }
180  }
181 
182  return n;
183 }
184 
185 // FIXME: Remove once we implement https://sft.its.cern.ch/jira/browse/ROOT-6284
186 // When building with -fmodules, it instantiates all pending instantiations,
187 // instead of delaying them until the end of the translation unit.
188 // We 'got away with' probably because the use and the definition of the
189 // explicit specialization do not occur in the same TU.
190 //
191 // In case we are building with -fmodules, we need to forward declare the
192 // specialization in order to compile the dictionary G__Core.cxx.
193 template <> void TParameter<Long64_t>::Streamer(TBuffer &R__b);
194 template<> TClass *TParameter<Long64_t>::Class();
195 
196 #endif