Teuchos - Trilinos Tools Package Version of the Day
Teuchos_StandardParameterEntryValidators.cpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Teuchos_StandardParameterEntryValidators.hpp"
00030 
00031 
00032 std::string Teuchos::getVerbosityLevelParameterValueName(
00033   const EVerbosityLevel verbLevel
00034   )
00035 {
00036   switch(verbLevel) {
00037     case VERB_DEFAULT:
00038       return "default";
00039     case VERB_NONE:
00040       return "none";
00041     case VERB_LOW:
00042       return "low";
00043     case VERB_MEDIUM:
00044       return "medium";
00045     case VERB_HIGH:
00046       return "high";
00047     case VERB_EXTREME:
00048       return "extreme";
00049     default:
00050       TEST_FOR_EXCEPT("Should never get here!");
00051   }
00052   return ""; // Never get here!
00053 }
00054 
00055 
00056 Teuchos::RCP<
00057   Teuchos::StringToIntegralParameterEntryValidator<Teuchos::EVerbosityLevel>
00058   >
00059 Teuchos::verbosityLevelParameterEntryValidator(
00060   std::string const& defaultParameterName
00061   )
00062 {
00063   return rcp(
00064     new StringToIntegralParameterEntryValidator<EVerbosityLevel>(
00065       tuple<std::string>(
00066         getVerbosityLevelParameterValueName(VERB_DEFAULT),
00067         getVerbosityLevelParameterValueName(VERB_NONE),
00068         getVerbosityLevelParameterValueName(VERB_LOW),
00069         getVerbosityLevelParameterValueName(VERB_MEDIUM),
00070         getVerbosityLevelParameterValueName(VERB_HIGH),
00071         getVerbosityLevelParameterValueName(VERB_EXTREME)
00072         ),
00073       tuple<std::string>(
00074         "Use level set in code",
00075         "Produce no output",
00076         "Produce minimal output",
00077         "Produce a little more output",
00078         "Produce a higher level of output",
00079         "Produce the highest level of output"
00080         ),
00081       tuple<EVerbosityLevel>(
00082         VERB_DEFAULT,
00083         VERB_NONE,
00084         VERB_LOW,
00085         VERB_MEDIUM,
00086         VERB_HIGH,
00087         VERB_EXTREME
00088         ),
00089       defaultParameterName
00090       )
00091     );
00092 }
00093 
00094 
00095 namespace Teuchos {
00096 
00097 
00098 //
00099 // AnyNumberParameterEntryValidator
00100 //
00101 
00102 
00103 // Constructors
00104 
00105 
00106 AnyNumberParameterEntryValidator::AnyNumberParameterEntryValidator()
00107   :preferredType_(PREFER_DOUBLE),
00108    acceptedTypes_(AcceptedTypes())
00109 {
00110   finishInitialization();
00111 }
00112 
00113 
00114 AnyNumberParameterEntryValidator::AnyNumberParameterEntryValidator(
00115   EPreferredType const preferredType,
00116   AcceptedTypes const& acceptedTypes
00117   )
00118   :preferredType_(preferredType),
00119    acceptedTypes_(acceptedTypes)
00120 {
00121   finishInitialization();
00122 }
00123 
00124 
00125 //  Local non-virtual validated lookup functions
00126 
00127 
00128 int AnyNumberParameterEntryValidator::getInt(
00129   const ParameterEntry &entry, const std::string &paramName
00130   ,const std::string &sublistName, const bool activeQuery
00131   ) const
00132 {
00133   const any &anyValue = entry.getAny(activeQuery);
00134   if( acceptedTypes_.allowInt() && anyValue.type() == typeid(int) )
00135     return any_cast<int>(anyValue);
00136   if( acceptedTypes_.allowDouble() && anyValue.type() == typeid(double) )
00137     return static_cast<int>(any_cast<double>(anyValue));
00138   if( acceptedTypes_.allowString() && anyValue.type() == typeid(std::string) )
00139     return std::atoi(any_cast<std::string>(anyValue).c_str());
00140   throwTypeError(entry,paramName,sublistName);
00141   return 0; // Will never get here!
00142 }
00143 
00144 
00145 double AnyNumberParameterEntryValidator::getDouble(
00146   const ParameterEntry &entry, const std::string &paramName
00147   ,const std::string &sublistName, const bool activeQuery
00148   ) const
00149 {
00150   const any &anyValue = entry.getAny(activeQuery);
00151   if( acceptedTypes_.allowInt() && anyValue.type() == typeid(int) )
00152     return static_cast<double>(any_cast<int>(anyValue));
00153   if( acceptedTypes_.allowDouble() && anyValue.type() == typeid(double) )
00154     return any_cast<double>(anyValue);
00155   if( acceptedTypes_.allowString() && anyValue.type() == typeid(std::string) )
00156     return std::atof(any_cast<std::string>(anyValue).c_str());
00157   throwTypeError(entry,paramName,sublistName);
00158   return 0.0; // Will never get here!
00159 }
00160 
00161 
00162 std::string AnyNumberParameterEntryValidator::getString(
00163   const ParameterEntry &entry, const std::string &paramName
00164   ,const std::string &sublistName, const bool activeQuery
00165   ) const
00166 {
00167   const any &anyValue = entry.getAny(activeQuery);
00168   if( acceptedTypes_.allowInt() && anyValue.type() == typeid(int) )
00169     return Utils::toString(any_cast<int>(anyValue));
00170   if( acceptedTypes_.allowDouble() && anyValue.type() == typeid(double) )
00171     return Utils::toString(any_cast<double>(anyValue));
00172   if( acceptedTypes_.allowString() && anyValue.type() == typeid(std::string) )
00173     return any_cast<std::string>(anyValue);
00174   throwTypeError(entry,paramName,sublistName);
00175   return ""; // Will never get here!
00176 }
00177 
00178 
00179 int AnyNumberParameterEntryValidator::getInt(
00180   ParameterList &paramList, const std::string &paramName
00181   ,const int defaultValue
00182   ) const
00183 {
00184   const ParameterEntry *entry = paramList.getEntryPtr(paramName);
00185   if(entry) return getInt(*entry,paramName,paramList.name(),true);
00186   return paramList.get(paramName,defaultValue);
00187 }
00188 
00189 
00190 double AnyNumberParameterEntryValidator::getDouble(
00191   ParameterList &paramList, const std::string &paramName
00192   ,const double defaultValue
00193   ) const
00194 {
00195   const ParameterEntry *entry = paramList.getEntryPtr(paramName);
00196   if(entry) return getDouble(*entry,paramName,paramList.name(),true);
00197   return paramList.get(paramName,defaultValue);
00198 }
00199 
00200 
00201 std::string AnyNumberParameterEntryValidator::getString(
00202   ParameterList &paramList, const std::string &paramName
00203   ,const std::string &defaultValue
00204   ) const
00205 {
00206   const ParameterEntry *entry = paramList.getEntryPtr(paramName);
00207   if(entry) return getString(*entry,paramName,paramList.name(),true);
00208   return paramList.get(paramName,defaultValue);
00209 }
00210 
00211   
00212 // Overridden from ParameterEntryValidator
00213 
00214 
00215 void AnyNumberParameterEntryValidator::printDoc(
00216   std::string         const& docString
00217   ,std::ostream            & out
00218   ) const
00219 {
00220   StrUtils::printLines(out,"# ",docString);
00221   out << "#  Accepted types: " << acceptedTypesString_ << ".\n";
00222 }
00223 
00224 
00225 RCP<const Array<std::string> >
00226 AnyNumberParameterEntryValidator::validStringValues() const
00227 {
00228   return null;
00229 }
00230 
00231 
00232 void AnyNumberParameterEntryValidator::validate(
00233   ParameterEntry  const& entry
00234   ,std::string    const& paramName
00235   ,std::string    const& sublistName
00236   ) const
00237 {
00238   // Validate (any of the get functions will do!)
00239   getInt(entry,paramName,sublistName,false);
00240 }
00241 
00242 
00243 void AnyNumberParameterEntryValidator::validateAndModify(
00244   std::string const& paramName,
00245   std::string const& sublistName,
00246   ParameterEntry * entry
00247   ) const
00248 {
00249   TEST_FOR_EXCEPT(0==entry);
00250   switch(preferredType_) {
00251     case PREFER_INT:
00252       entry->setValue(
00253         getInt(*entry,paramName,sublistName,false),
00254         false // isDefault
00255         );
00256       break;
00257     case PREFER_DOUBLE:
00258       entry->setValue(
00259         getDouble(*entry,paramName,sublistName,false),
00260         false // isDefault
00261         );
00262       break;
00263     case PREFER_STRING:
00264       entry->setValue(
00265         getString(*entry,paramName,sublistName,false),
00266         false // isDefault
00267         );
00268       break;
00269     default:
00270       TEST_FOR_EXCEPT("Error, Invalid EPreferredType value!");
00271   }
00272 }
00273 
00274 
00275 // private
00276 
00277 
00278 void AnyNumberParameterEntryValidator::finishInitialization()
00279 {
00280 
00281   std::ostringstream oss;
00282   bool addedType = false;
00283   if(acceptedTypes_.allowInt()) {
00284     oss << "\"int\"";
00285     addedType = true;
00286   }
00287   if(acceptedTypes_.allowDouble()) {
00288     if(addedType) oss << ", ";
00289     oss << "\"double\"";
00290     addedType = true;
00291   }
00292   if(acceptedTypes_.allowString()) {
00293     if(addedType) oss << ", ";
00294     oss << "\"string\"";
00295     addedType = true;
00296   }
00297   acceptedTypesString_ = oss.str();
00298 }
00299 
00300 
00301 void AnyNumberParameterEntryValidator::throwTypeError(
00302   ParameterEntry  const& entry
00303   ,std::string    const& paramName
00304   ,std::string    const& sublistName
00305   ) const
00306 {
00307   const std::string &entryName = entry.getAny(false).typeName();
00308   TEST_FOR_EXCEPTION_PURE_MSG(
00309     true, Exceptions::InvalidParameterType
00310     ,"Error, the parameter {paramName=\""<<paramName<<"\""
00311     ",type=\""<<entryName<<"\"}"
00312     << "\nin the sublist \"" << sublistName << "\""
00313     << "\nhas the wrong type."
00314     << "\n\nThe accepted types are: " << acceptedTypesString_ << "!";
00315     );
00316 }
00317 
00318 
00319 } // namespace Teuchos
00320 
00321 
00322 // Nonmmeber helper functions
00323 
00324 Teuchos::RCP<Teuchos::AnyNumberParameterEntryValidator>
00325 Teuchos::anyNumberParameterEntryValidator(
00326   AnyNumberParameterEntryValidator::EPreferredType const preferredType,
00327   AnyNumberParameterEntryValidator::AcceptedTypes const& acceptedTypes
00328   )
00329 {
00330   return rcp(
00331     new AnyNumberParameterEntryValidator(
00332       preferredType, acceptedTypes
00333       )
00334     );
00335 }
00336 
00337 
00338 void Teuchos::setIntParameter(
00339   std::string const& paramName,
00340   int const value, std::string const& docString,
00341   ParameterList *paramList,
00342   AnyNumberParameterEntryValidator::AcceptedTypes const& acceptedTypes
00343   )
00344 {
00345   TEST_FOR_EXCEPT(0==paramList);
00346   const RCP<const ParameterEntryValidator> paramEntryValidator =  
00347     anyNumberParameterEntryValidator(
00348       AnyNumberParameterEntryValidator::PREFER_INT, acceptedTypes
00349       );
00350   paramList->set(paramName, value, docString, paramEntryValidator);
00351 }
00352 
00353 
00354 void Teuchos::setDoubleParameter(
00355   std::string const& paramName,
00356   double const& value, std::string const& docString,
00357   ParameterList *paramList,
00358   AnyNumberParameterEntryValidator::AcceptedTypes const& acceptedTypes
00359   )
00360 {
00361   TEST_FOR_EXCEPT(0==paramList);
00362   const RCP<const ParameterEntryValidator> paramEntryValidator =  
00363     anyNumberParameterEntryValidator(
00364       AnyNumberParameterEntryValidator::PREFER_DOUBLE, acceptedTypes
00365       );
00366   paramList->set(paramName, value, docString, paramEntryValidator);
00367 }
00368 
00369 
00370 void Teuchos::setNumericStringParameter(
00371   std::string const& paramName,
00372   std::string const& value, std::string const& docString,
00373   ParameterList *paramList,
00374   AnyNumberParameterEntryValidator::AcceptedTypes const& acceptedTypes
00375   )
00376 {
00377   TEST_FOR_EXCEPT(0==paramList);
00378   const RCP<const ParameterEntryValidator> paramEntryValidator =  
00379     anyNumberParameterEntryValidator(
00380       AnyNumberParameterEntryValidator::PREFER_STRING, acceptedTypes
00381       );
00382   paramList->set(paramName, value, docString, paramEntryValidator);
00383 }
00384 
00385 
00386 int Teuchos::getIntParameter(
00387   ParameterList const& paramList,
00388   std::string const& paramName
00389   )
00390 {
00391   const ParameterEntry &entry = paramList.getEntry(paramName);
00392   RCP<const AnyNumberParameterEntryValidator>
00393     anyNumValidator = rcp_dynamic_cast<const AnyNumberParameterEntryValidator>(
00394       entry.validator()
00395       );
00396   if ( !is_null(anyNumValidator) )
00397     return anyNumValidator->getInt(entry,paramName,paramList.name());
00398   if ( typeid(int) == entry.getAny().type() )
00399     return any_cast<int>(entry.getAny());
00400   // Try the do the conversion which might fail!
00401   const AnyNumberParameterEntryValidator myAnyNumValidator;
00402   return myAnyNumValidator.getInt(entry,paramName,paramList.name());
00403 }
00404 
00405 
00406 double Teuchos::getDoubleParameter(
00407   ParameterList const& paramList,
00408   std::string const& paramName
00409   )
00410 {
00411   const ParameterEntry &entry = paramList.getEntry(paramName);
00412   RCP<const AnyNumberParameterEntryValidator>
00413     anyNumValidator = rcp_dynamic_cast<const AnyNumberParameterEntryValidator>(
00414       entry.validator()
00415       );
00416   if ( !is_null(anyNumValidator) )
00417     return anyNumValidator->getDouble(entry,paramName,paramList.name());
00418   if ( typeid(double) == entry.getAny().type() )
00419     return any_cast<double>(entry.getAny());
00420   // Try the do the conversion which might fail!
00421   const AnyNumberParameterEntryValidator myAnyNumValidator;
00422   return myAnyNumValidator.getDouble(entry,paramName,paramList.name());
00423 }
00424 
00425 
00426 std::string Teuchos::getNumericStringParameter(
00427   ParameterList const& paramList,
00428   std::string const& paramName
00429   )
00430 {
00431   const ParameterEntry &entry = paramList.getEntry(paramName);
00432   RCP<const AnyNumberParameterEntryValidator>
00433     anyNumValidator = rcp_dynamic_cast<const AnyNumberParameterEntryValidator>(
00434       entry.validator()
00435       );
00436   if ( !is_null(anyNumValidator) )
00437     return anyNumValidator->getString(entry,paramName,paramList.name());
00438   if ( typeid(std::string) == entry.getAny().type() )
00439     return any_cast<std::string>(entry.getAny());
00440   // Try the do the conversion which might fail!
00441   const AnyNumberParameterEntryValidator myAnyNumValidator;
00442   return myAnyNumValidator.getString(entry,paramName,paramList.name());
00443 }
00444 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines