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   static std::string concreteName( const ParameterList& /*t2*/ )
00598     { return name(); }
00599 };
00600 
00605 bool operator==( const ParameterList& list1, const ParameterList& list2 );
00606 
00611 inline
00612 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00613 {
00614   return !( list1 == list2 );
00615 }
00616 
00625 bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00626 
00627 // /////////////////////////////////////////////////////
00628 // Inline and Template Function Definitions
00629 
00630 inline
00631 ParameterList& ParameterList::setName( const std::string &name_in )
00632 {
00633   name_ = name_in;
00634   return *this;
00635 }
00636 
00637 // Set functions
00638 
00639 template<typename T>
00640 inline
00641 ParameterList& ParameterList::set(
00642   std::string const& name_in, T const& value_in, std::string const& docString_in,
00643   RCP<const ParameterEntryValidator> const& validator_in
00644   )
00645 {
00646   ParameterEntry &foundEntry = params_[name_in]; // Will add the entry if not exists
00647   foundEntry.setValue(value_in,false,docString_in,validator_in);
00648   // Validate the value *after* you set it.  It is important to use
00649   // entry.validator() instead of validator since validator might be null!
00650   if(foundEntry.validator().get())
00651     foundEntry.validator()->validate(foundEntry,name_in,this->name());
00652   return *this;
00653 }
00654 
00655 inline
00656 ParameterList& ParameterList::set(
00657   std::string const& name_in, char value[], std::string const& docString
00658   ,RCP<const ParameterEntryValidator> const& validator
00659   ) 
00660 { return set( name_in, std::string(value), docString, validator ); }
00661 
00662 inline
00663 ParameterList& ParameterList::set(
00664   const std::string& name_in, const char value[], const std::string &docString
00665   ,RCP<const ParameterEntryValidator> const& validator
00666   ) 
00667 { return set( name_in, std::string(value), docString, validator ); }
00668 
00669 inline
00670 ParameterList& ParameterList::set(
00671   std::string const& name_in, ParameterList const& value, std::string const& /*docString*/
00672   )
00673 {
00674   sublist(name_in) = value;
00675   return *this;
00676 }
00677 
00678 inline
00679 ParameterList& ParameterList::setEntry(std::string const& name_in, ParameterEntry const& entry_in)
00680 {
00681   params_[name_in] = entry_in;
00682   return *this;
00683 }
00684 
00685 // Get functions
00686 
00687 template<typename T>
00688 T& ParameterList::get(const std::string& name_in, T def_value)
00689 {
00690   ConstIterator i = params_.find(name_in);
00691     
00692   // The parameter was not found, add it to the list
00693   if (i == params_.end()) {
00694     params_[name_in].setValue(def_value, true);
00695     i = params_.find(name_in);
00696   } else {
00697     // The parameter was found, make sure it is the same type as T.
00698     this->template validateEntryType<T>("get", name_in, entry(i));
00699   }
00700 
00701   // Return the value of the parameter
00702   return getValue<T>(entry(i));
00703 }
00704 
00705 inline
00706 std::string& ParameterList::get(const std::string& name_in, char def_value[])
00707 { return get(name_in, std::string(def_value)); }
00708 
00709 inline
00710 std::string& ParameterList::get(const std::string& name_in, const char def_value[])
00711 { return get(name_in, std::string(def_value)); }
00712 
00713 template<typename T>
00714 T& ParameterList::get(const std::string& name_in) 
00715 {
00716   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00717   validateEntryExists("get",name_in,foundEntry);
00718   this->template validateEntryType<T>("get",name_in,*foundEntry);
00719   return getValue<T>(*foundEntry);
00720 }
00721   
00722 template<typename T>
00723 const T& ParameterList::get(const std::string& name_in) const
00724 {
00725   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00726   validateEntryExists("get",name_in,foundEntry);
00727   this->template validateEntryType<T>("get",name_in,*foundEntry);
00728   return getValue<T>(*foundEntry);
00729 }
00730 
00731 template<typename T>
00732 inline
00733 T* ParameterList::getPtr(const std::string& name_in) 
00734 {
00735   ConstIterator i = params_.find(name_in);
00736   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00737     return NULL;
00738   return &getValue<T>(entry(i));
00739 }
00740   
00741 template<typename T>
00742 inline
00743 const T* ParameterList::getPtr(const std::string& name_in) const
00744 {
00745   ConstIterator i = params_.find(name_in);
00746   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00747     return NULL;
00748   return &getValue<T>(entry(i));
00749 }
00750 
00751 inline
00752 ParameterEntry& ParameterList::getEntry(const std::string& name_in)
00753 {
00754   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00755   validateEntryExists("get",name_in,foundEntry);
00756   return *foundEntry;
00757 }
00758   
00759 inline
00760 const ParameterEntry& ParameterList::getEntry(const std::string& name_in) const
00761 {
00762   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00763   validateEntryExists("get",name_in,foundEntry);
00764   return *foundEntry;
00765 }
00766 
00767 inline
00768 ParameterEntry*
00769 ParameterList::getEntryPtr(const std::string& name_in)
00770 {
00771   Map::iterator i = params_.find(name_in);
00772   if ( i == params_.end() )
00773     return NULL;
00774   return &entry(i);
00775 }
00776 
00777 inline
00778 const ParameterEntry*
00779 ParameterList::getEntryPtr(const std::string& name_in) const
00780 {
00781   ConstIterator i = params_.find(name_in);
00782   if ( i == params_.end() )
00783     return NULL;
00784   return &entry(i);
00785 }
00786 
00787 // Attribute Functions
00788 
00789 inline
00790 const std::string& ParameterList::name() const
00791 {
00792   return name_;
00793 }
00794   
00795 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00796 template<typename T>
00797 bool ParameterList::isType(const std::string& name_in, T* /*ptr*/) const
00798 {
00799   ConstIterator i = params_.find(name_in);
00800   // If parameter doesn't exist, return false.
00801   if (i == params_.end()) 
00802     return false;
00803   return entry(i).getAny().type() == typeid(T);
00804 }
00805 #endif
00806   
00807 template<typename T>
00808 bool ParameterList::isType(const std::string& name_in) const
00809 {
00810   ConstIterator i = params_.find(name_in);
00811   // If parameter doesn't exist, return false.
00812   if (i == params_.end()) 
00813     return false;
00814   return entry(i).getAny().type() == typeid(T);
00815 }
00816 
00817 
00818 // private
00819 
00820 
00821 template<typename T>
00822 inline
00823 void ParameterList::validateEntryType(
00824   const std::string &/*funcName*/, const std::string &name_in,
00825   const ParameterEntry &entry_in
00826   ) const
00827 {
00828   TEST_FOR_EXCEPTION_PURE_MSG(
00829     entry_in.getAny().type() != typeid(T), Exceptions::InvalidParameterType
00830     ,"Error!  An attempt was made to access parameter \""<<name_in<<"\""
00831     " of type \""<<entry_in.getAny().typeName()<<"\""
00832     "\nin the parameter (sub)list \""<<this->name()<<"\""
00833     "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00834     );
00835 }
00836 
00837 // //////////////////////////////////////
00838 // Helper functions
00839   
00846 template<typename T>
00847 T& getParameter( ParameterList& l, const std::string& name )
00848 {
00849   return l.template get<T>(name);
00850 }
00851   
00857 template<typename T>
00858 inline
00859 T& get( ParameterList& l, const std::string& name )
00860 {
00861   return getParameter<T>(l,name);
00862 }
00863   
00870 template<typename T>
00871 const T& getParameter( const ParameterList& l, const std::string& name )
00872 {
00873   return l.template get<T>(name);
00874 }
00875   
00883 template<typename T>
00884 inline
00885 T* getParameterPtr( ParameterList& l, const std::string& name )
00886 {
00887   return l.template getPtr<T>(name);
00888 }
00889   
00897 template<typename T>
00898 inline
00899 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00900 {
00901   return l.template getPtr<T>(name);
00902 }
00903   
00910 template<typename T>
00911 inline
00912 bool isParameterType( ParameterList& l, const std::string& name )
00913 {
00914   return l.isType( name, (T*)NULL );
00915 }
00916   
00923 template<typename T>
00924 inline
00925 bool isParameterType( const ParameterList& l, const std::string& name )
00926 {
00927   return l.isType( name, (T*)NULL );
00928 }
00929   
00941 template<typename T>
00942 void setStringParameterFromArray(
00943   const std::string          &paramName
00944   ,const Array<T>       &array
00945   ,ParameterList        *paramList
00946   )
00947 {
00948   TEST_FOR_EXCEPT(!paramList);
00949   paramList->set(paramName,toString(array));
00950 }
00951   
01016 template<typename T>
01017 Array<T> getArrayFromStringParameter(
01018   const ParameterList   &paramList
01019   ,const std::string         &paramName
01020   ,const int            arrayDim        = -1
01021   ,const bool           mustExist       = true
01022   )
01023 {
01024   std::string arrayStr;
01025   if(mustExist) {
01026     arrayStr = getParameter<std::string>(paramList,paramName);
01027   }
01028   else {
01029     const std::string
01030       *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01031     if(arrayStrPtr) {
01032       arrayStr = *arrayStrPtr;
01033     }
01034     else {
01035       return Array<T>(); // Return an empty array
01036     }
01037   }
01038   Array<T> a;
01039   try {
01040     a = fromStringToArray<T>(arrayStr);
01041   }
01042   catch( const InvalidArrayStringRepresentation &except ) {
01043     TEST_FOR_EXCEPTION_PURE_MSG(
01044       true, Exceptions::InvalidParameterValue
01045       ,"Error!  The parameter \""<<paramName<<"\"\n"
01046       "in the sublist \""<<paramList.name()<<"\"\n"
01047       "exists, but the std::string value:\n"
01048       "----------\n"
01049       <<arrayStr<<
01050       "\n----------\n"
01051       "is not a valid array represntation!"
01052       );
01053   }
01054   TEST_FOR_EXCEPTION_PURE_MSG(
01055     ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01056     ,Exceptions::InvalidParameterValue
01057     ,"Error!  The parameter \""<<paramName<<"\"\n"
01058     "in the sublist \""<<paramList.name()<<"\"\n"
01059     "exists and is a valid array, but the dimension of\n"
01060     "the read in array a.size() = " << a.size() << "\n"
01061     "was not equal to the expected size arrayDim = " << arrayDim << "!"
01062     );
01063   return a;
01064 }
01065 
01069 inline
01070 RCP<ParameterList> sublist(
01071   const RCP<ParameterList> &paramList, const std::string& name, bool mustAlreadyExist = false
01072   )
01073 {
01074   return rcpWithEmbeddedObjPostDestroy(
01075     &paramList->sublist(name,mustAlreadyExist), paramList, false );
01076 }
01077 
01081 inline
01082 RCP<const ParameterList> sublist(
01083   const RCP<const ParameterList> &paramList, const std::string& name
01084   )
01085 {
01086   return rcpWithEmbeddedObjPostDestroy(
01087     &paramList->sublist(name), paramList, false );
01088 }
01089   
01093 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01094 {
01095   return l.print(os);
01096 }
01097   
01098 } // end of Teuchos namespace
01099 
01100 #endif
01101 
01102 

Generated on Wed May 12 21:40:32 2010 for Teuchos - Trilinos Tools Package by  doxygen 1.4.7