#ifndef ROOT_TParameter
#define ROOT_TParameter
#ifndef ROOT_Riostream
#include "Riostream.h"
#endif
#ifndef ROOT_TClass
#include "TClass.h"
#endif
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TCollection
#include "TCollection.h"
#endif
#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TROOT
#include "TROOT.h"
#endif
template <class AParamType>
class TParameter : public TObject {
public:
enum EStatusBits { kMultiply = BIT(16),
kMax = BIT(17),
kMin = BIT(18),
kFirst = BIT(19),
kLast = BIT(20),
kIsConst = BIT(21)
};
private:
TString fName;
AParamType fVal;
void Reset() { ResetBit(kMultiply); ResetBit(kMax); ResetBit(kMin);
ResetBit(kFirst); ResetBit(kLast); }
public:
TParameter(): fVal() { Reset(); SetBit(kIsConst); }
TParameter(const char *name, const AParamType &val)
: fName(name), fVal(val) { Reset(); SetBit(kIsConst);}
TParameter(const char *name, const AParamType &val, char mergemode)
: fName(name), fVal(val) { SetMergeMode(mergemode); SetBit(kIsConst);}
~TParameter() { }
const char *GetName() const { return fName; }
const AParamType &GetVal() const { return fVal; }
Bool_t IsConst() const { return (TestBit(kIsConst) ? kTRUE : kFALSE); }
void SetVal(const AParamType &val) { fVal = val; }
void SetMergeMode(char mergemode = '+') {
Reset();
if (mergemode == '*') {
SetBit(kMultiply);
} else if (mergemode == 'M') {
SetBit(kMax);
} else if (mergemode == 'm') {
SetBit(kMin);
} else if (mergemode == 'f') {
SetBit(kFirst);
} else if (mergemode == 'l') {
SetBit(kLast);
}
}
virtual ULong_t Hash() const { return fName.Hash(); }
virtual Bool_t IsSortable() const { return kTRUE; }
virtual Int_t Compare(const TObject *obj) const {
if (this == obj) return 0;
return fName.CompareTo(obj->GetName());
}
virtual void ls(Option_t *) const {
TROOT::IndentLevel();
cout << "OBJ: " << IsA()->GetName() << "\t" << fName << " = " << fVal << endl;
}
virtual void Print(Option_t *) const {
TROOT::IndentLevel();
cout << IsA()->GetName() << "\t" << fName << " = " << fVal << endl;
}
virtual Int_t Merge(TCollection *in);
ClassDef(TParameter,2)
};
template <class AParamType>
inline Int_t TParameter<AParamType>::Merge(TCollection *in) {
TIter nxo(in);
Int_t n = 0;
while (TObject *o = nxo()) {
TParameter<AParamType> *c = dynamic_cast<TParameter<AParamType> *>(o);
if (c) {
if (fVal != c->GetVal()) ResetBit(kIsConst);
if (TestBit(kMultiply)) {
fVal *= c->GetVal();
} else if (TestBit(kMax)) {
if (c->GetVal() > fVal) fVal = c->GetVal();
} else if (TestBit(kMin)) {
if (c->GetVal() < fVal) fVal = c->GetVal();
} else if (TestBit(kLast)) {
fVal = c->GetVal();
} else if (!TestBit(kFirst)) {
fVal += c->GetVal();
}
n++;
}
}
return n;
}
template <>
inline Int_t TParameter<Bool_t>::Merge(TCollection *in)
{
TIter nxo(in);
Int_t n = 0;
while (TObject *o = nxo()) {
TParameter<Bool_t> *c = dynamic_cast<TParameter<Bool_t> *>(o);
if (c) {
if (fVal != (Bool_t) c->GetVal()) ResetBit(kIsConst);
if (TestBit(TParameter::kMultiply) || TestBit(kMin)) {
fVal &= (Bool_t) c->GetVal();
} else if (TestBit(kLast)) {
fVal = (Bool_t) c->GetVal();
} else if (!TestBit(kFirst) || TestBit(kMax)) {
fVal |= (Bool_t) c->GetVal();
}
n++;
}
}
return n;
}
#endif