Teuchos - Trilinos Tools Package Version of the Day
Teuchos_ParameterList.hpp
Go to the documentation of this file.
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 
00030 #ifndef TEUCHOS_PARAMETER_LIST_H
00031 #define TEUCHOS_PARAMETER_LIST_H
00032 
00037 #include "Teuchos_ParameterListExceptions.hpp"
00038 #include "Teuchos_ParameterEntry.hpp"
00039 #include "Teuchos_TestForException.hpp"
00040 #include "Teuchos_RCP.hpp"
00041 #include "Teuchos_Array.hpp"
00042 #include "Teuchos_map.hpp"
00043 
00048 namespace Teuchos {
00049 
00053 enum EValidateUsed {
00054   VALIDATE_USED_ENABLED   /*< \brief Validate that parameters in <tt>*this</tt> list
00055                               set using the default value are present in
00056                               the validation list */
00057   ,VALIDATE_USED_DISABLED /*< \brief Do not validate that parameters in <tt>*this</tt> list
00058                               set using the default value are present in
00059                               the validation list */
00060 };
00061 
00065 enum EValidateDefaults {
00066   VALIDATE_DEFAULTS_ENABLED   /*< \brief Validate that parameters in <tt>*this</tt> list
00067                                   set using the default value are present in
00068                                    the validation list */
00069   ,VALIDATE_DEFAULTS_DISABLED /*< \brief Do not validate that parameters in <tt>*this</tt> list
00070                                   set using the default value are present in
00071                                   the validation list */
00072 };
00073 
00087 class TEUCHOS_LIB_DLL_EXPORT ParameterList {
00088 
00090   typedef Teuchos::map<std::string, ParameterEntry> Map;
00091 
00093   typedef Map::iterator Iterator;
00094   
00095 public:
00096 
00098 
00099 
00101   typedef Map::const_iterator ConstIterator;
00102 
00104   class PrintOptions {
00105   public:
00106     PrintOptions() : indent_(0), showTypes_(false), showFlags_(false), showDoc_(false) {}
00107     PrintOptions& indent(int _indent)        { indent_ = _indent; return *this; }
00108     PrintOptions& showTypes(bool _showTypes) { showTypes_ = _showTypes; return *this; }
00109     PrintOptions& showFlags(bool _showFlags) { showFlags_ = _showFlags; return *this; }
00110     PrintOptions& showDoc(bool _showDoc)     { showDoc_ = _showDoc; return *this; }
00111     PrintOptions& incrIndent(int indents)    { indent_ += indents; return *this; }
00112     int indent() const { return indent_; }
00113     bool showTypes() const { return showTypes_; }
00114     bool showFlags() const { return showFlags_; }
00115     bool showDoc() const { return showDoc_; }
00116     PrintOptions copy() const { return PrintOptions(*this); }
00117   private:
00118     int    indent_;
00119     bool   showTypes_;
00120     bool   showFlags_;
00121     bool   showDoc_;
00122   };
00123 
00125   
00127 
00128 
00130   ParameterList();
00131 
00133   ParameterList(const std::string &name);
00134   
00136   ParameterList(const ParameterList& source);
00137   
00139   virtual ~ParameterList();
00140 
00142   
00144 
00145 
00148   ParameterList& setName( const std::string &name );
00149   
00153   ParameterList& operator=(const ParameterList& source);
00154   
00162   ParameterList& setParameters(const ParameterList& source);
00163   
00173   ParameterList& setParametersNotAlreadySet(const ParameterList& source);
00174 
00182   ParameterList& disableRecursiveValidation();
00183   
00192   template<typename T>
00193   ParameterList& set(
00194     std::string const& name, T const& value, std::string const& docString = ""
00195     ,RCP<const ParameterEntryValidator> const& validator = null
00196     );
00197 
00201   ParameterList& set(
00202     std::string const& name, char value[], std::string const& docString = ""
00203     ,RCP<const ParameterEntryValidator> const& validator = null
00204     );
00205 
00209   ParameterList& set(
00210     std::string const& name, const char value[], std::string const& docString = ""
00211     ,RCP<const ParameterEntryValidator> const& validator = null
00212     );
00213 
00216   ParameterList& set(
00217     std::string const& name, ParameterList const& value, std::string const& docString = ""
00218     );
00219 
00224   ParameterList& setEntry(const std::string& name, const ParameterEntry& entry);
00225 
00227   
00229 
00230   
00241   template<typename T>
00242   T& get(const std::string& name, T def_value);
00243 
00247   std::string& get(const std::string& name, char def_value[]);
00248   
00252   std::string& get(const std::string& name, const char def_value[]);
00253   
00261   template<typename T>
00262   T& get(const std::string& name);
00263   
00271   template<typename T>
00272   const T& get(const std::string& name) const;  
00273   
00279   template<typename T>
00280   inline
00281   T* getPtr(const std::string& name);
00282   
00288   template<typename T>
00289   inline
00290   const T* getPtr(const std::string& name) const;  
00291   
00297   ParameterEntry& getEntry(const std::string& name);  
00298   
00304   inline
00305   const ParameterEntry& getEntry(const std::string& name) const;  
00306   
00309   inline
00310   ParameterEntry* getEntryPtr(const std::string& name);  
00311   
00314   inline
00315   const ParameterEntry* getEntryPtr(const std::string& name) const;  
00316 
00318 
00320 
00321  
00335   bool remove(
00336     std::string const& name, bool throwIfNotExists = true
00337     );
00338 
00340   
00342 
00343 
00349   ParameterList& sublist(
00350     const std::string& name, bool mustAlreadyExist = false
00351     ,const std::string& docString = ""
00352     );
00353   
00358   const ParameterList& sublist(const std::string& name) const;
00359 
00361   
00363 
00364 
00366   const std::string& name() const;
00367 
00373   bool isParameter(const std::string& name) const;
00374   
00380   bool isSublist(const std::string& name) const;
00381   
00388   template<typename T>
00389   bool isType(const std::string& name) const;
00390 
00391 #ifndef DOXYGEN_SHOULD_SKIP_THIS  
00392 
00402   template<typename T>
00403   bool isType(const std::string& name, T* ptr) const;
00404 #endif
00405 
00407   
00409 
00410 
00413   std::ostream& print(std::ostream& os, const PrintOptions &printOptions) const;
00414 
00417   std::ostream& print(std::ostream& os, int indent = 0, bool showTypes = false, bool showFlags = true ) const;
00418   
00420   void unused(std::ostream& os) const;
00421 
00423   std::string currentParametersString() const;
00424 
00426 
00428 
00429 
00431   ConstIterator begin() const ;
00432 
00434   ConstIterator end() const ;
00435 
00437   const ParameterEntry& entry(ConstIterator i) const;
00438   
00440   const std::string& name(ConstIterator i) const;
00441 
00443 
00445 
00446 
00491   void validateParameters(
00492     ParameterList const& validParamList,
00493     int const depth = 1000,
00494     EValidateUsed const validateUsed = VALIDATE_USED_ENABLED,
00495     EValidateDefaults const validateDefaults = VALIDATE_DEFAULTS_ENABLED
00496     ) const;
00497 
00535   void validateParametersAndSetDefaults(
00536     ParameterList const& validParamList,
00537     int const depth = 1000
00538     );
00539 
00541   
00542 private: // Functions
00543  
00545   Iterator nonconstBegin();
00547   Iterator nonconstEnd();
00549   ParameterEntry& entry(Iterator i);
00551   void validateEntryExists( const std::string &funcName, const std::string &name, const ParameterEntry *entry ) const;
00553   template<typename T>
00554   void validateEntryType( const std::string &funcName, const std::string &name, const ParameterEntry &entry ) const;
00556   void updateSubListNames(int depth = 0);
00557   
00558 private: // Data members
00559 
00561   std::string name_;
00562 
00564 //use pragmas to disable some false-positive warnings for windows sharedlibs export
00565 #ifdef _MSC_VER
00566 #pragma warning(push)
00567 #pragma warning(disable:4251)
00568 #endif
00569   Map params_;
00570 #ifdef _MSC_VER
00571 #pragma warning(pop)
00572 #endif
00573 
00575   bool disableRecursiveValidation_;
00576 
00577 };
00578 
00579 
00584 inline
00585 RCP<ParameterList> parameterList()
00586 {
00587   return rcp(new ParameterList);
00588 }
00589 
00590 
00595 inline
00596 RCP<ParameterList> parameterList(const std::string &name)
00597 {
00598   return rcp(new ParameterList(name));
00599 }
00600   
00601 
00606 inline
00607 RCP<ParameterList> parameterList(const ParameterList& source)
00608 {
00609   return rcp(new ParameterList(source));
00610 }
00611 
00612 
00617 template<>
00618 class TEUCHOS_LIB_DLL_EXPORT TypeNameTraits<ParameterList> {
00619 public:
00620   static std::string name() { return "ParameterList"; }
00621   static std::string concreteName( const ParameterList& /*t2*/ )
00622     { return name(); }
00623 };
00624 
00629 TEUCHOS_LIB_DLL_EXPORT bool operator==( const ParameterList& list1, const ParameterList& list2 );
00630 
00635 inline
00636 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00637 {
00638   return !( list1 == list2 );
00639 }
00640 
00649 TEUCHOS_LIB_DLL_EXPORT bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00650 
00651 
00652 // /////////////////////////////////////////////////////
00653 // Inline and Template Function Definitions
00654 
00655 
00656 inline
00657 ParameterList& ParameterList::setName( const std::string &name_in )
00658 {
00659   name_ = name_in;
00660   return *this;
00661 }
00662 
00663 // Set functions
00664 
00665 template<typename T>
00666 inline
00667 ParameterList& ParameterList::set(
00668   std::string const& name_in, T const& value_in, std::string const& docString_in,
00669   RCP<const ParameterEntryValidator> const& validator_in
00670   )
00671 {
00672   ParameterEntry &foundEntry = params_[name_in]; // Will add the entry if not exists
00673   foundEntry.setValue(value_in,false,docString_in,validator_in);
00674   // Validate the value *after* you set it.  It is important to use
00675   // entry.validator() instead of validator since validator might be null!
00676   if(foundEntry.validator().get())
00677     foundEntry.validator()->validate(foundEntry,name_in,this->name());
00678   return *this;
00679 }
00680 
00681 inline
00682 ParameterList& ParameterList::set(
00683   std::string const& name_in, char value[], std::string const& docString
00684   ,RCP<const ParameterEntryValidator> const& validator
00685   ) 
00686 { return set( name_in, std::string(value), docString, validator ); }
00687 
00688 inline
00689 ParameterList& ParameterList::set(
00690   const std::string& name_in, const char value[], const std::string &docString
00691   ,RCP<const ParameterEntryValidator> const& validator
00692   ) 
00693 { return set( name_in, std::string(value), docString, validator ); }
00694 
00695 inline
00696 ParameterList& ParameterList::set(
00697   std::string const& name_in, ParameterList const& value, std::string const& /*docString*/
00698   )
00699 {
00700   sublist(name_in) = value;
00701   return *this;
00702 }
00703 
00704 inline
00705 ParameterList& ParameterList::setEntry(std::string const& name_in, ParameterEntry const& entry_in)
00706 {
00707   params_[name_in] = entry_in;
00708   return *this;
00709 }
00710 
00711 // Get functions
00712 
00713 template<typename T>
00714 T& ParameterList::get(const std::string& name_in, T def_value)
00715 {
00716   ConstIterator i = params_.find(name_in);
00717     
00718   // The parameter was not found, add it to the list
00719   if (i == params_.end()) {
00720     params_[name_in].setValue(def_value, true);
00721     i = params_.find(name_in);
00722   } else {
00723     // The parameter was found, make sure it is the same type as T.
00724     this->template validateEntryType<T>("get", name_in, entry(i));
00725   }
00726 
00727   // Return the value of the parameter
00728   return getValue<T>(entry(i));
00729 }
00730 
00731 inline
00732 std::string& ParameterList::get(const std::string& name_in, char def_value[])
00733 { return get(name_in, std::string(def_value)); }
00734 
00735 inline
00736 std::string& ParameterList::get(const std::string& name_in, const char def_value[])
00737 { return get(name_in, std::string(def_value)); }
00738 
00739 template<typename T>
00740 T& ParameterList::get(const std::string& name_in) 
00741 {
00742   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00743   validateEntryExists("get",name_in,foundEntry);
00744   this->template validateEntryType<T>("get",name_in,*foundEntry);
00745   return getValue<T>(*foundEntry);
00746 }
00747   
00748 template<typename T>
00749 const T& ParameterList::get(const std::string& name_in) const
00750 {
00751   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00752   validateEntryExists("get",name_in,foundEntry);
00753   this->template validateEntryType<T>("get",name_in,*foundEntry);
00754   return getValue<T>(*foundEntry);
00755 }
00756 
00757 template<typename T>
00758 inline
00759 T* ParameterList::getPtr(const std::string& name_in) 
00760 {
00761   ConstIterator i = params_.find(name_in);
00762   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00763     return NULL;
00764   return &getValue<T>(entry(i));
00765 }
00766   
00767 template<typename T>
00768 inline
00769 const T* ParameterList::getPtr(const std::string& name_in) const
00770 {
00771   ConstIterator i = params_.find(name_in);
00772   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00773     return NULL;
00774   return &getValue<T>(entry(i));
00775 }
00776 
00777 inline
00778 ParameterEntry& ParameterList::getEntry(const std::string& name_in)
00779 {
00780   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00781   validateEntryExists("get",name_in,foundEntry);
00782   return *foundEntry;
00783 }
00784   
00785 inline
00786 const ParameterEntry& ParameterList::getEntry(const std::string& name_in) const
00787 {
00788   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00789   validateEntryExists("get",name_in,foundEntry);
00790   return *foundEntry;
00791 }
00792 
00793 inline
00794 ParameterEntry*
00795 ParameterList::getEntryPtr(const std::string& name_in)
00796 {
00797   Map::iterator i = params_.find(name_in);
00798   if ( i == params_.end() )
00799     return NULL;
00800   return &entry(i);
00801 }
00802 
00803 inline
00804 const ParameterEntry*
00805 ParameterList::getEntryPtr(const std::string& name_in) const
00806 {
00807   ConstIterator i = params_.find(name_in);
00808   if ( i == params_.end() )
00809     return NULL;
00810   return &entry(i);
00811 }
00812 
00813 // Attribute Functions
00814 
00815 inline
00816 const std::string& ParameterList::name() const
00817 {
00818   return name_;
00819 }
00820   
00821 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00822 template<typename T>
00823 bool ParameterList::isType(const std::string& name_in, T* /*ptr*/) const
00824 {
00825   ConstIterator i = params_.find(name_in);
00826   // If parameter doesn't exist, return false.
00827   if (i == params_.end()) 
00828     return false;
00829   return entry(i).getAny().type() == typeid(T);
00830 }
00831 #endif
00832   
00833 template<typename T>
00834 bool ParameterList::isType(const std::string& name_in) const
00835 {
00836   ConstIterator i = params_.find(name_in);
00837   // If parameter doesn't exist, return false.
00838   if (i == params_.end()) 
00839     return false;
00840   return entry(i).getAny().type() == typeid(T);
00841 }
00842 
00843 
00844 // private
00845 
00846 
00847 template<typename T>
00848 inline
00849 void ParameterList::validateEntryType(
00850   const std::string &/*funcName*/, const std::string &name_in,
00851   const ParameterEntry &entry_in
00852   ) const
00853 {
00854   TEST_FOR_EXCEPTION_PURE_MSG(
00855     entry_in.getAny().type() != typeid(T), Exceptions::InvalidParameterType
00856     ,"Error!  An attempt was made to access parameter \""<<name_in<<"\""
00857     " of type \""<<entry_in.getAny().typeName()<<"\""
00858     "\nin the parameter (sub)list \""<<this->name()<<"\""
00859     "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00860     );
00861 }
00862 
00863 // //////////////////////////////////////
00864 // Helper functions
00865   
00872 template<typename T>
00873 T& getParameter( ParameterList& l, const std::string& name )
00874 {
00875   return l.template get<T>(name);
00876 }
00877   
00883 template<typename T>
00884 inline
00885 T& get( ParameterList& l, const std::string& name )
00886 {
00887   return getParameter<T>(l,name);
00888 }
00889   
00896 template<typename T>
00897 const T& getParameter( const ParameterList& l, const std::string& name )
00898 {
00899   return l.template get<T>(name);
00900 }
00901   
00909 template<typename T>
00910 inline
00911 T* getParameterPtr( ParameterList& l, const std::string& name )
00912 {
00913   return l.template getPtr<T>(name);
00914 }
00915   
00923 template<typename T>
00924 inline
00925 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00926 {
00927   return l.template getPtr<T>(name);
00928 }
00929   
00936 template<typename T>
00937 inline
00938 bool isParameterType( ParameterList& l, const std::string& name )
00939 {
00940   return l.isType( name, (T*)NULL );
00941 }
00942   
00949 template<typename T>
00950 inline
00951 bool isParameterType( const ParameterList& l, const std::string& name )
00952 {
00953   return l.isType( name, (T*)NULL );
00954 }
00955   
00967 template<typename T>
00968 void setStringParameterFromArray(
00969   const std::string          &paramName
00970   ,const Array<T>       &array
00971   ,ParameterList        *paramList
00972   )
00973 {
00974   TEST_FOR_EXCEPT(!paramList);
00975   paramList->set(paramName,toString(array));
00976 }
00977   
01042 template<typename T>
01043 Array<T> getArrayFromStringParameter(
01044   const ParameterList   &paramList
01045   ,const std::string         &paramName
01046   ,const int            arrayDim        = -1
01047   ,const bool           mustExist       = true
01048   )
01049 {
01050   std::string arrayStr;
01051   if(mustExist) {
01052     arrayStr = getParameter<std::string>(paramList,paramName);
01053   }
01054   else {
01055     const std::string
01056       *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01057     if(arrayStrPtr) {
01058       arrayStr = *arrayStrPtr;
01059     }
01060     else {
01061       return Array<T>(); // Return an empty array
01062     }
01063   }
01064   Array<T> a;
01065   try {
01066     a = fromStringToArray<T>(arrayStr);
01067   }
01068   catch( const InvalidArrayStringRepresentation&) {
01069     TEST_FOR_EXCEPTION_PURE_MSG(
01070       true, Exceptions::InvalidParameterValue
01071       ,"Error!  The parameter \""<<paramName<<"\"\n"
01072       "in the sublist \""<<paramList.name()<<"\"\n"
01073       "exists, but the std::string value:\n"
01074       "----------\n"
01075       <<arrayStr<<
01076       "\n----------\n"
01077       "is not a valid array represntation!"
01078       );
01079   }
01080   TEST_FOR_EXCEPTION_PURE_MSG(
01081     ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01082     ,Exceptions::InvalidParameterValue
01083     ,"Error!  The parameter \""<<paramName<<"\"\n"
01084     "in the sublist \""<<paramList.name()<<"\"\n"
01085     "exists and is a valid array, but the dimension of\n"
01086     "the read in array a.size() = " << a.size() << "\n"
01087     "was not equal to the expected size arrayDim = " << arrayDim << "!"
01088     );
01089   return a;
01090 }
01091 
01095 inline
01096 RCP<ParameterList> sublist(
01097   const RCP<ParameterList> &paramList, const std::string& name, bool mustAlreadyExist = false
01098   )
01099 {
01100   return rcpWithEmbeddedObjPostDestroy(
01101     &paramList->sublist(name,mustAlreadyExist), paramList, false );
01102 }
01103 
01107 inline
01108 RCP<const ParameterList> sublist(
01109   const RCP<const ParameterList> &paramList, const std::string& name
01110   )
01111 {
01112   return rcpWithEmbeddedObjPostDestroy(
01113     &paramList->sublist(name), paramList, false );
01114 }
01115   
01119 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01120 {
01121   return l.print(os);
01122 }
01123   
01124 } // end of Teuchos namespace
01125 
01126 #endif
01127 
01128 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines