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 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   T* getPtr(const std::string& name);
00281   
00287   template<typename T>
00288   const T* getPtr(const std::string& name) const;  
00289   
00295   ParameterEntry& getEntry(const std::string& name);  
00296   
00302   const ParameterEntry& getEntry(const std::string& name) const;  
00303   
00306   ParameterEntry* getEntryPtr(const std::string& name);  
00307   
00310   const ParameterEntry* getEntryPtr(const std::string& name) const;  
00311 
00313 
00315 
00316  
00330   bool remove(
00331     std::string const& name, bool throwIfNotExists = true
00332     );
00333 
00335   
00337 
00338 
00344   ParameterList& sublist(
00345     const std::string& name, bool mustAlreadyExist = false
00346     ,const std::string& docString = ""
00347     );
00348   
00353   const ParameterList& sublist(const std::string& name) const;
00354 
00356   
00358 
00359 
00361   const std::string& name() const;
00362 
00368   bool isParameter(const std::string& name) const;
00369   
00375   bool isSublist(const std::string& name) const;
00376   
00383   template<typename T>
00384   bool isType(const std::string& name) const;
00385 
00386 #ifndef DOXYGEN_SHOULD_SKIP_THIS  
00387 
00397   template<typename T>
00398   bool isType(const std::string& name, T* ptr) const;
00399 #endif
00400 
00402   
00404 
00405 
00408   std::ostream& print(std::ostream& os, const PrintOptions &printOptions) const;
00409 
00412   std::ostream& print(std::ostream& os, int indent = 0, bool showTypes = false, bool showFlags = true ) const;
00413   
00415   void unused(std::ostream& os) const;
00416 
00418   std::string currentParametersString() const;
00419 
00421 
00423 
00424 
00426   ConstIterator begin() const ;
00427 
00429   ConstIterator end() const ;
00430 
00432   const ParameterEntry& entry(ConstIterator i) const;
00433   
00435   const std::string& name(ConstIterator i) const;
00436 
00438 
00440 
00441 
00486   void validateParameters(
00487     ParameterList const& validParamList,
00488     int const depth = 1000,
00489     EValidateUsed const validateUsed = VALIDATE_USED_ENABLED,
00490     EValidateDefaults const validateDefaults = VALIDATE_DEFAULTS_ENABLED
00491     ) const;
00492 
00530   void validateParametersAndSetDefaults(
00531     ParameterList const& validParamList,
00532     int const depth = 1000
00533     );
00534 
00536   
00537 private: // Functions
00538  
00540   Iterator nonconstBegin();
00542   Iterator nonconstEnd();
00544   ParameterEntry& entry(Iterator i);
00546   void validateEntryExists( const std::string &funcName, const std::string &name, const ParameterEntry *entry ) const;
00548   template<typename T>
00549   void validateEntryType( const std::string &funcName, const std::string &name, const ParameterEntry &entry ) const;
00551   void updateSubListNames(int depth = 0);
00552   
00553 private: // Data members
00554 
00556   std::string name_;
00558   Map params_;
00560   bool disableRecursiveValidation_;
00561 
00562 };
00563 
00564 
00566 inline
00567 RCP<ParameterList> parameterList()
00568 {
00569   return rcp(new ParameterList);
00570 }
00571 
00572 
00574 inline
00575 RCP<ParameterList> parameterList(const std::string &name)
00576 {
00577   return rcp(new ParameterList(name));
00578 }
00579   
00581 inline
00582 RCP<ParameterList> parameterList(const ParameterList& source)
00583 {
00584   return rcp(new ParameterList(source));
00585 }
00586 
00587 
00588 
00593 template<>
00594 class TypeNameTraits<ParameterList> {
00595 public:
00596   static std::string name() { return "ParameterList"; }
00597 };
00598 
00603 bool operator==( const ParameterList& list1, const ParameterList& list2 );
00604 
00609 inline
00610 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00611 {
00612   return !( list1 == list2 );
00613 }
00614 
00623 bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00624 
00625 // /////////////////////////////////////////////////////
00626 // Inline and Template Function Definitions
00627 
00628 inline
00629 ParameterList& ParameterList::setName( const std::string &name )
00630 {
00631   name_ = name;
00632   return *this;
00633 }
00634 
00635 // Set functions
00636 
00637 template<typename T>
00638 inline
00639 ParameterList& ParameterList::set(
00640   std::string const& name, T const& value, std::string const& docString
00641   ,RCP<const ParameterEntryValidator> const& validator
00642   )
00643 {
00644   ParameterEntry &entry = params_[name]; // Will add the entry if not exists
00645   entry.setValue(value,false,docString,validator);
00646   // Validate the value *after* you set it.  It is important to use
00647   // entry.validator() instead of validator since validator might be null!
00648   if(entry.validator().get())
00649     entry.validator()->validate(entry,name,this->name());
00650   return *this;
00651 }
00652 
00653 inline
00654 ParameterList& ParameterList::set(
00655   std::string const& name, char value[], std::string const& docString
00656   ,RCP<const ParameterEntryValidator> const& validator
00657   ) 
00658 { return set( name, std::string(value), docString, validator ); }
00659 
00660 inline
00661 ParameterList& ParameterList::set(
00662   const std::string& name, const char value[], const std::string &docString
00663   ,RCP<const ParameterEntryValidator> const& validator
00664   ) 
00665 { return set( name, std::string(value), docString, validator ); }
00666 
00667 inline
00668 ParameterList& ParameterList::set(
00669   std::string const& name, ParameterList const& value, std::string const& docString
00670   )
00671 {
00672   sublist(name) = value;
00673   return *this;
00674 }
00675 
00676 inline
00677 ParameterList& ParameterList::setEntry(std::string const& name, ParameterEntry const& entry)
00678 {
00679   params_[name] = entry;
00680   return *this;
00681 }
00682 
00683 // Get functions
00684 
00685 template<typename T>
00686 T& ParameterList::get(const std::string& name, T def_value)
00687 {
00688   ConstIterator i = params_.find(name);
00689     
00690   // The parameter was not found, add it to the list
00691   if (i == params_.end()) {
00692     params_[name].setValue(def_value, true);
00693     i = params_.find(name);
00694   } else {
00695     // The parameter was found, make sure it is the same type as T.
00696     this->template validateEntryType<T>("get",name,entry(i));
00697   }
00698 
00699   // Return the value of the parameter
00700   return getValue<T>(entry(i));
00701 }
00702 
00703 inline
00704 std::string& ParameterList::get(const std::string& name, char def_value[])
00705 { return get(name, std::string(def_value)); }
00706 
00707 inline
00708 std::string& ParameterList::get(const std::string& name, const char def_value[])
00709 { return get(name, std::string(def_value)); }
00710 
00711 template<typename T>
00712 T& ParameterList::get(const std::string& name) 
00713 {
00714   ParameterEntry *entry = this->getEntryPtr(name);
00715   validateEntryExists("get",name,entry);
00716   this->template validateEntryType<T>("get",name,*entry);
00717   return getValue<T>(*entry);
00718 }
00719   
00720 template<typename T>
00721 const T& ParameterList::get(const std::string& name) const
00722 {
00723   const ParameterEntry *entry = this->getEntryPtr(name);
00724   validateEntryExists("get",name,entry);
00725   this->template validateEntryType<T>("get",name,*entry);
00726   return getValue<T>(*entry);
00727 }
00728 
00729 template<typename T>
00730 inline
00731 T* ParameterList::getPtr(const std::string& name) 
00732 {
00733   ConstIterator i = params_.find(name);
00734   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00735     return NULL;
00736   return &getValue<T>(entry(i));
00737 }
00738   
00739 template<typename T>
00740 inline
00741 const T* ParameterList::getPtr(const std::string& name) const
00742 {
00743   ConstIterator i = params_.find(name);
00744   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00745     return NULL;
00746   return &getValue<T>(entry(i));
00747 }
00748 
00749 inline
00750 ParameterEntry& ParameterList::getEntry(const std::string& name)
00751 {
00752   ParameterEntry *entry = this->getEntryPtr(name);
00753   validateEntryExists("get",name,entry);
00754   return *entry;
00755 }
00756   
00757 inline
00758 const ParameterEntry& ParameterList::getEntry(const std::string& name) const
00759 {
00760   const ParameterEntry *entry = this->getEntryPtr(name);
00761   validateEntryExists("get",name,entry);
00762   return *entry;
00763 }
00764 
00765 inline
00766 ParameterEntry*
00767 ParameterList::getEntryPtr(const std::string& name)
00768 {
00769   Map::iterator i = params_.find(name);
00770   if ( i == params_.end() )
00771     return NULL;
00772   return &entry(i);
00773 }
00774 
00775 inline
00776 const ParameterEntry*
00777 ParameterList::getEntryPtr(const std::string& name) const
00778 {
00779   ConstIterator i = params_.find(name);
00780   if ( i == params_.end() )
00781     return NULL;
00782   return &entry(i);
00783 }
00784 
00785 // Attribute Functions
00786 
00787 inline
00788 const std::string& ParameterList::name() const
00789 {
00790   return name_;
00791 }
00792   
00793 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00794 template<typename T>
00795 bool ParameterList::isType(const std::string& name, T* ptr) const
00796 {
00797   ConstIterator i = params_.find(name);
00798   // If parameter doesn't exist, return false.
00799   if (i == params_.end()) 
00800     return false;
00801   return entry(i).getAny().type() == typeid(T);
00802 }
00803 #endif
00804   
00805 template<typename T>
00806 bool ParameterList::isType(const std::string& name) const
00807 {
00808   ConstIterator i = params_.find(name);
00809   // If parameter doesn't exist, return false.
00810   if (i == params_.end()) 
00811     return false;
00812   return entry(i).getAny().type() == typeid(T);
00813 }
00814 
00815 
00816 // private
00817 
00818 
00819 template<typename T>
00820 inline
00821 void ParameterList::validateEntryType(
00822   const std::string &funcName, const std::string &name,
00823   const ParameterEntry &entry
00824   ) const
00825 {
00826   TEST_FOR_EXCEPTION_PURE_MSG(
00827     (entry.getAny().type() != typeid(T))
00828     && (entry.getAny().typeName() != TypeNameTraits<T>::name())
00829     , Exceptions::InvalidParameterType
00830     ,"Error!  An attempt was made to access parameter \""<<name<<"\""
00831     " of type \""<<entry.getAny().typeName()<<"\""
00832     "\nin the parameter (sub)list \""<<this->name()<<"\""
00833     "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00834     );
00835   // 2007/11/27: rabartl: Above, I removed the ifdef for ENABLE_SHARED since
00836   // the g++ compiler flagged this as non-ansi code.  We will leave the second
00837   // test for the name.  This should not be a performance problem since the
00838   // most comon use case will be for validate to pass in which case the second
00839   // comparison for the name will never be executed since the first typeid(T)
00840   // test will pass.
00841 }
00842 
00843 // //////////////////////////////////////
00844 // Helper functions
00845   
00852 template<typename T>
00853 T& getParameter( ParameterList& l, const std::string& name )
00854 {
00855   return l.template get<T>(name);
00856 }
00857   
00863 template<typename T>
00864 inline
00865 T& get( ParameterList& l, const std::string& name )
00866 {
00867   return getParameter<T>(l,name);
00868 }
00869   
00876 template<typename T>
00877 const T& getParameter( const ParameterList& l, const std::string& name )
00878 {
00879   return l.template get<T>(name);
00880 }
00881   
00889 template<typename T>
00890 inline
00891 T* getParameterPtr( ParameterList& l, const std::string& name )
00892 {
00893   return l.template getPtr<T>(name);
00894 }
00895   
00903 template<typename T>
00904 inline
00905 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00906 {
00907   return l.template getPtr<T>(name);
00908 }
00909   
00916 template<typename T>
00917 inline
00918 bool isParameterType( ParameterList& l, const std::string& name )
00919 {
00920   return l.isType( name, (T*)NULL );
00921 }
00922   
00929 template<typename T>
00930 inline
00931 bool isParameterType( const ParameterList& l, const std::string& name )
00932 {
00933   return l.isType( name, (T*)NULL );
00934 }
00935   
00947 template<typename T>
00948 void setStringParameterFromArray(
00949   const std::string          &paramName
00950   ,const Array<T>       &array
00951   ,ParameterList        *paramList
00952   )
00953 {
00954   TEST_FOR_EXCEPT(!paramList);
00955   paramList->set(paramName,toString(array));
00956 }
00957   
01022 template<typename T>
01023 Array<T> getArrayFromStringParameter(
01024   const ParameterList   &paramList
01025   ,const std::string         &paramName
01026   ,const int            arrayDim        = -1
01027   ,const bool           mustExist       = true
01028   )
01029 {
01030   std::string arrayStr;
01031   if(mustExist) {
01032     arrayStr = getParameter<std::string>(paramList,paramName);
01033   }
01034   else {
01035     const std::string
01036       *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01037     if(arrayStrPtr) {
01038       arrayStr = *arrayStrPtr;
01039     }
01040     else {
01041       return Array<T>(); // Return an empty array
01042     }
01043   }
01044   Array<T> a;
01045   try {
01046     a = fromStringToArray<T>(arrayStr);
01047   }
01048   catch( const InvalidArrayStringRepresentation &except ) {
01049     TEST_FOR_EXCEPTION_PURE_MSG(
01050       true, Exceptions::InvalidParameterValue
01051       ,"Error!  The parameter \""<<paramName<<"\"\n"
01052       "in the sublist \""<<paramList.name()<<"\"\n"
01053       "exists, but the std::string value:\n"
01054       "----------\n"
01055       <<arrayStr<<
01056       "\n----------\n"
01057       "is not a valid array represntation!"
01058       );
01059   }
01060   TEST_FOR_EXCEPTION_PURE_MSG(
01061     ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01062     ,Exceptions::InvalidParameterValue
01063     ,"Error!  The parameter \""<<paramName<<"\"\n"
01064     "in the sublist \""<<paramList.name()<<"\"\n"
01065     "exists and is a valid array, but the dimension of\n"
01066     "the read in array a.size() = " << a.size() << "\n"
01067     "was not equal to the expected size arrayDim = " << arrayDim << "!"
01068     );
01069   return a;
01070 }
01071 
01075 inline
01076 RCP<ParameterList> sublist(
01077   const RCP<ParameterList> &paramList, const std::string& name, bool mustAlreadyExist = false
01078   )
01079 {
01080   RCP<ParameterList>
01081     sublist = Teuchos::rcp(&paramList->sublist(name,mustAlreadyExist),false);
01082   set_extra_data(paramList,"masterParamList",&sublist);
01083   return sublist;
01084 }
01085 
01089 inline
01090 RCP<const ParameterList> sublist(
01091   const RCP<const ParameterList> &paramList, const std::string& name
01092   )
01093 {
01094   RCP<const ParameterList>
01095     sublist = Teuchos::rcp(&paramList->sublist(name),false);
01096   set_extra_data(paramList,"masterParamList",&sublist);
01097   return sublist;
01098 }
01099   
01103 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01104 {
01105   return l.print(os);
01106 }
01107   
01108 } // end of Teuchos namespace
01109 
01110 #endif
01111 
01112 

Generated on Tue Oct 20 12:45:26 2009 for Teuchos - Trilinos Tools Package by doxygen 1.4.7