Warning, /include/ThePEG/Interface/Parameter.tcc is written in an unsupported language. File is not indexed.
0001 // -*- C++ -*-
0002 //
0003 // Parameter.tcc is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 //
0010 // This is the implementation of the non-inlined templated member
0011 // functions of the Parameter and ParameterTBase classes.
0012 //
0013
0014 namespace ThePEG {
0015
0016 template <typename Type>
0017 string ParameterTBase<Type>::type() const {
0018 if ( std::numeric_limits<Type>::is_integer ) return "Pi";
0019 if ( typeid(Type) == typeid(string) ) return "Ps";
0020 return "Pf";
0021 }
0022
0023 template <typename Type>
0024 string ParameterTBase<Type>::doxygenType() const {
0025 string lim = "";
0026 if ( !limited() ) lim = "Unlimited ";
0027 if ( std::numeric_limits<Type>::is_integer ) return lim + "Integer parameter";
0028 if ( typeid(Type) == typeid(string) ) return "Character string parameter";
0029 return lim + "Parameter";
0030 }
0031
0032 template <typename Type>
0033 inline void
0034 ParameterTBase<Type>::setImpl(InterfacedBase & i,
0035 string newValue, StandardT)
0036 const {
0037 istringstream is(newValue);
0038 if ( unit() > Type() ) {
0039 double t;
0040 is >> t;
0041 tset(i, umult(t, unit()));
0042 } else {
0043 Type t = Type();
0044 is >> t;
0045 tset(i, t);
0046 }
0047 }
0048
0049 template <typename Type>
0050 inline void
0051 ParameterTBase<Type>::setImpl(InterfacedBase & i,
0052 string newValue, DimensionT)
0053 const {
0054 istringstream is(newValue);
0055 double t;
0056 is >> t;
0057 // if 'is' has no more chars, all stream ops below are no-ops
0058 is.ignore(); // skip the connecting char
0059 string suffix;
0060 is >> suffix;
0061 checkUnitConsistency(suffix);
0062 tset(i, umult(t, unit()));
0063 }
0064
0065 template <typename Type>
0066 inline void
0067 ParameterTBase<Type>::setImpl(InterfacedBase & i,
0068 string newValue, EnumT)
0069 const {
0070 istringstream is(newValue);
0071 int t;
0072 is >> t;
0073 tset(i, Type(t));
0074 }
0075
0076 // Macs need a visible template specialization.
0077 template <>
0078 void ParameterTBase<Energy>::
0079 checkUnitConsistency(string suffix) const;
0080
0081 template <>
0082 void ParameterTBase<Energy2>::
0083 checkUnitConsistency(string suffix) const;
0084
0085 template <>
0086 void ParameterTBase<Length>::
0087 checkUnitConsistency(string suffix) const;
0088
0089
0090 template <typename T>
0091 void ParameterTBase<T>::
0092 checkUnitConsistency(string suffix) const {
0093 if ( ! suffix.empty() ) {
0094 Throw<InterfaceException>()
0095 << name()
0096 << ": unit suffix " << suffix << " will be ignored.\n"
0097 << "The unit specified in the parameter definition is used instead.\n\n"
0098 << "To proceed, remove the unit suffix in the input file or \n"
0099 << "request unit support for " << suffix << " to be added.\n\n"
0100 << Exception::setuperror;
0101 }
0102 }
0103
0104
0105
0106 template <typename T>
0107 void ParameterTBase<T>::
0108 set(InterfacedBase & i, string newValue) const {
0109 setImpl(i, newValue, typename TypeTraits<T>::DimType());
0110 }
0111
0112 template <typename Type>
0113 string ParameterTBase<Type>::
0114 get(const InterfacedBase & i) const {
0115 ostringstream os;
0116 putUnit(os, tget(i));
0117 return os.str();
0118 }
0119
0120 template <typename Type>
0121 string ParameterTBase<Type>::
0122 minimum(const InterfacedBase & i) const {
0123 ostringstream os;
0124 if ( ParameterBase::lowerLimit() ) putUnit(os, tminimum(i));
0125 return os.str();
0126 }
0127
0128 template <typename Type>
0129 string ParameterTBase<Type>::
0130 maximum(const InterfacedBase & i) const {
0131 ostringstream os;
0132 if ( ParameterBase::upperLimit() ) putUnit(os, tmaximum(i));
0133 return os.str();
0134 }
0135
0136 template <typename Type>
0137 string ParameterTBase<Type>::
0138 def(const InterfacedBase & i) const {
0139 ostringstream os;
0140 putUnit(os, tdef(i));
0141 return os.str();
0142 }
0143
0144 template <typename T, typename Type>
0145 void Parameter<T,Type>::tset(InterfacedBase & i, Type newValue) const
0146 {
0147 if ( InterfaceBase::readOnly() ) throw InterExReadOnly(*this, i);
0148 T * t = dynamic_cast<T *>(&i);
0149 if ( !t ) throw InterExClass(*this, i);
0150 if ( ( ParameterBase::lowerLimit() && newValue < tminimum(i) ) ||
0151 ( ParameterBase::upperLimit() && newValue > tmaximum(i) ) )
0152 throw ParExSetLimit(*this, i, newValue);
0153 Type oldValue = tget(i);
0154 if ( theSetFn ) {
0155 try { (t->*theSetFn)(newValue); }
0156 catch (InterfaceException & e) { throw e; }
0157 catch ( ... ) { throw ParExSetUnknown(*this, i, newValue); }
0158 } else {
0159 if ( theMember ) t->*theMember = newValue;
0160 else throw InterExSetup(*this, i);
0161 }
0162 if ( !InterfaceBase::dependencySafe() && oldValue != tget(i)) i.touch();
0163 }
0164
0165 template <typename T>
0166 void Parameter<T,string>::tset(InterfacedBase & i, string newValue) const
0167 {
0168 if ( InterfaceBase::readOnly() ) throw InterExReadOnly(*this, i);
0169 T * t = dynamic_cast<T *>(&i);
0170 if ( !t ) throw InterExClass(*this, i);
0171 string oldValue = tget(i);
0172 if ( theSetFn ) {
0173 try { (t->*theSetFn)(newValue); }
0174 catch (InterfaceException & e) { throw e; }
0175 catch ( ... ) { throw ParExSetUnknown(*this, i, newValue); }
0176 } else {
0177 if ( theMember ) t->*theMember = newValue;
0178 else throw InterExSetup(*this, i);
0179 }
0180 if ( !InterfaceBase::dependencySafe() && oldValue != tget(i)) i.touch();
0181 }
0182
0183 template <typename T, typename Type>
0184 Type Parameter<T,Type>::tget(const InterfacedBase & i) const
0185 {
0186 const T * t = dynamic_cast<const T *>(&i);
0187 if ( !t ) throw InterExClass(*this, i);
0188 if ( theGetFn ) {
0189 try { return (t->*theGetFn)(); }
0190 catch (InterfaceException & e) { throw e; }
0191 catch ( ... ) { throw ParExGetUnknown(*this, i, "current"); }
0192 }
0193 if ( theMember ) return t->*theMember;
0194 else throw InterExSetup(*this, i);
0195 }
0196
0197 template <typename T>
0198 string Parameter<T,string>::tget(const InterfacedBase & i) const
0199 {
0200 const T * t = dynamic_cast<const T *>(&i);
0201 if ( !t ) throw InterExClass(*this, i);
0202 if ( theGetFn ) {
0203 try { return (t->*theGetFn)(); }
0204 catch (InterfaceException & e) { throw e; }
0205 catch ( ... ) { throw ParExGetUnknown(*this, i, "current"); }
0206 }
0207 if ( theMember ) return t->*theMember;
0208 else throw InterExSetup(*this, i);
0209 }
0210
0211 template <typename T, typename Type>
0212 Type Parameter<T,Type>::tminimum(const InterfacedBase & i) const
0213 {
0214 if ( theMinFn ) {
0215 const T * t = dynamic_cast<const T *>(&i);
0216 if ( !t ) throw InterExClass(*this, i);
0217 try { return max(theMin, (t->*theMinFn)()); }
0218 catch (InterfaceException & e) { throw e; }
0219 catch ( ... ) { throw ParExGetUnknown(*this, i, "minimum"); }
0220 }
0221 return theMin;
0222 }
0223
0224 template <typename T, typename Type>
0225 Type Parameter<T,Type>::tmaximum(const InterfacedBase & i) const
0226 {
0227 if ( theMaxFn ) {
0228 const T * t = dynamic_cast<const T *>(&i);
0229 if ( !t ) throw InterExClass(*this, i);
0230 try { return min(theMax, (t->*theMaxFn)()); }
0231 catch (InterfaceException & e) { throw e; }
0232 catch ( ... ) { throw ParExGetUnknown(*this, i, "maximum"); }
0233 }
0234 return theMax;
0235 }
0236
0237 template <typename T, typename Type>
0238 Type Parameter<T,Type>::tdef(const InterfacedBase & i) const
0239 {
0240 if ( theDefFn ) {
0241 const T * t = dynamic_cast<const T *>(&i);
0242 if ( !t ) throw InterExClass(*this, i);
0243 try { return (t->*theDefFn)(); }
0244 catch (InterfaceException & e) { throw e; }
0245 catch ( ... ) { throw ParExGetUnknown(*this, i, "default"); }
0246 }
0247 return theDef;
0248 }
0249
0250 template <typename T>
0251 string Parameter<T,string>::tdef(const InterfacedBase & i) const
0252 {
0253 if ( theDefFn ) {
0254 const T * t = dynamic_cast<const T *>(&i);
0255 if ( !t ) throw InterExClass(*this, i);
0256 try { return (t->*theDefFn)(); }
0257 catch (InterfaceException & e) { throw e; }
0258 catch ( ... ) { throw ParExGetUnknown(*this, i, "default"); }
0259 }
0260 return theDef;
0261 }
0262
0263 template <typename T, typename Type>
0264 void Parameter<T,Type>::doxygenDescription(ostream & os) const {
0265 ParameterTBase<Type>::doxygenDescription(os);
0266 os << "<b>Default value:</b> ";
0267 this->putUnit(os, theDef);
0268 if ( theDefFn ) os << " (May be changed by member function.)";
0269 if ( ParameterBase::lowerLimit() ) {
0270 os << "<br>\n<b>Minimum value:</b> ";
0271 this->putUnit(os, theMin);
0272 if ( theMinFn ) os << " (May be changed by member function.)";
0273 }
0274 if ( ParameterBase::upperLimit() ) {
0275 os << "<br>\n<b>Maximum value:</b> ";
0276 this->putUnit(os, theMax);
0277 if ( theMaxFn ) os << " (May be changed by member function.)";
0278 }
0279 os << "<br>\n";
0280 }
0281
0282 template <typename T>
0283 void Parameter<T,string>::doxygenDescription(ostream & os) const {
0284 ParameterTBase<string>::doxygenDescription(os);
0285 os << "<b>Default value:</b> " << theDef;
0286 if ( theDefFn ) os << " (May be changed by member function.)";
0287 os << "<br>\n";
0288 }
0289
0290 namespace {
0291 template <typename T>
0292 inline
0293 void ostreamInsert(ostream & os, T v, DimensionT) {
0294 os << ounit(v, T::baseunit());
0295 }
0296
0297 template <typename T>
0298 inline
0299 void ostreamInsert(ostream & os, T v, StandardT) {
0300 os << v;
0301 }
0302
0303 template <typename T>
0304 inline
0305 void ostreamInsert(ostream & os, T v, EnumT) {
0306 os << v;
0307 }
0308 }
0309
0310 template <typename T>
0311 ParExSetLimit::ParExSetLimit(const InterfaceBase & i,
0312 const InterfacedBase & o, T v) {
0313 theMessage << "Could not set the parameter \"" << i.name()
0314 << "\" for the object \"" << o.name() << "\" to ";
0315 ostreamInsert(theMessage,v,typename TypeTraits<T>::DimType() );
0316 theMessage << " because the value is outside the specified limits.";
0317 severity(setuperror);
0318 }
0319
0320 template <typename T>
0321 ParExSetUnknown::ParExSetUnknown(const InterfaceBase & i,
0322 const InterfacedBase & o, T v) {
0323 theMessage << "Could not set the parameter \"" << i.name()
0324 << "\" for the object \"" << o.name() << "\" to ";
0325 ostreamInsert(theMessage,v,typename TypeTraits<T>::DimType() );
0326 theMessage << " because the set function threw an unknown exception.";
0327 severity(setuperror);
0328 }
0329
0330 }
0331