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 
00581 inline
00582 RCP<ParameterList> parameterList()
00583 {
00584   return rcp(new ParameterList);
00585 }
00586 
00587 
00589 inline
00590 RCP<ParameterList> parameterList(const std::string &name)
00591 {
00592   return rcp(new ParameterList(name));
00593 }
00594   
00596 inline
00597 RCP<ParameterList> parameterList(const ParameterList& source)
00598 {
00599   return rcp(new ParameterList(source));
00600 }
00601 
00602 
00603 
00608 template<>
00609 class TEUCHOS_LIB_DLL_EXPORT TypeNameTraits<ParameterList> {
00610 public:
00611   static std::string name() { return "ParameterList"; }
00612   static std::string concreteName( const ParameterList& /*t2*/ )
00613     { return name(); }
00614 };
00615 
00620 TEUCHOS_LIB_DLL_EXPORT bool operator==( const ParameterList& list1, const ParameterList& list2 );
00621 
00626 inline
00627 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00628 {
00629   return !( list1 == list2 );
00630 }
00631 
00640 TEUCHOS_LIB_DLL_EXPORT bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00641 
00642 // /////////////////////////////////////////////////////
00643 // Inline and Template Function Definitions
00644 
00645 inline
00646 ParameterList& ParameterList::setName( const std::string &name_in )
00647 {
00648   name_ = name_in;
00649   return *this;
00650 }
00651 
00652 // Set functions
00653 
00654 template<typename T>
00655 inline
00656 ParameterList& ParameterList::set(
00657   std::string const& name_in, T const& value_in, std::string const& docString_in,
00658   RCP<const ParameterEntryValidator> const& validator_in
00659   )
00660 {
00661   ParameterEntry &foundEntry = params_[name_in]; // Will add the entry if not exists
00662   foundEntry.setValue(value_in,false,docString_in,validator_in);
00663   // Validate the value *after* you set it.  It is important to use
00664   // entry.validator() instead of validator since validator might be null!
00665   if(foundEntry.validator().get())
00666     foundEntry.validator()->validate(foundEntry,name_in,this->name());
00667   return *this;
00668 }
00669 
00670 inline
00671 ParameterList& ParameterList::set(
00672   std::string const& name_in, char value[], std::string const& docString
00673   ,RCP<const ParameterEntryValidator> const& validator
00674   ) 
00675 { return set( name_in, std::string(value), docString, validator ); }
00676 
00677 inline
00678 ParameterList& ParameterList::set(
00679   const std::string& name_in, const char value[], const std::string &docString
00680   ,RCP<const ParameterEntryValidator> const& validator
00681   ) 
00682 { return set( name_in, std::string(value), docString, validator ); }
00683 
00684 inline
00685 ParameterList& ParameterList::set(
00686   std::string const& name_in, ParameterList const& value, std::string const& /*docString*/
00687   )
00688 {
00689   sublist(name_in) = value;
00690   return *this;
00691 }
00692 
00693 inline
00694 ParameterList& ParameterList::setEntry(std::string const& name_in, ParameterEntry const& entry_in)
00695 {
00696   params_[name_in] = entry_in;
00697   return *this;
00698 }
00699 
00700 // Get functions
00701 
00702 template<typename T>
00703 T& ParameterList::get(const std::string& name_in, T def_value)
00704 {
00705   ConstIterator i = params_.find(name_in);
00706     
00707   // The parameter was not found, add it to the list
00708   if (i == params_.end()) {
00709     params_[name_in].setValue(def_value, true);
00710     i = params_.find(name_in);
00711   } else {
00712     // The parameter was found, make sure it is the same type as T.
00713     this->template validateEntryType<T>("get", name_in, entry(i));
00714   }
00715 
00716   // Return the value of the parameter
00717   return getValue<T>(entry(i));
00718 }
00719 
00720 inline
00721 std::string& ParameterList::get(const std::string& name_in, char def_value[])
00722 { return get(name_in, std::string(def_value)); }
00723 
00724 inline
00725 std::string& ParameterList::get(const std::string& name_in, const char def_value[])
00726 { return get(name_in, std::string(def_value)); }
00727 
00728 template<typename T>
00729 T& ParameterList::get(const std::string& name_in) 
00730 {
00731   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00732   validateEntryExists("get",name_in,foundEntry);
00733   this->template validateEntryType<T>("get",name_in,*foundEntry);
00734   return getValue<T>(*foundEntry);
00735 }
00736   
00737 template<typename T>
00738 const T& ParameterList::get(const std::string& name_in) const
00739 {
00740   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00741   validateEntryExists("get",name_in,foundEntry);
00742   this->template validateEntryType<T>("get",name_in,*foundEntry);
00743   return getValue<T>(*foundEntry);
00744 }
00745 
00746 template<typename T>
00747 inline
00748 T* ParameterList::getPtr(const std::string& name_in) 
00749 {
00750   ConstIterator i = params_.find(name_in);
00751   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00752     return NULL;
00753   return &getValue<T>(entry(i));
00754 }
00755   
00756 template<typename T>
00757 inline
00758 const T* ParameterList::getPtr(const std::string& name_in) const
00759 {
00760   ConstIterator i = params_.find(name_in);
00761   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00762     return NULL;
00763   return &getValue<T>(entry(i));
00764 }
00765 
00766 inline
00767 ParameterEntry& ParameterList::getEntry(const std::string& name_in)
00768 {
00769   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00770   validateEntryExists("get",name_in,foundEntry);
00771   return *foundEntry;
00772 }
00773   
00774 inline
00775 const ParameterEntry& ParameterList::getEntry(const std::string& name_in) const
00776 {
00777   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00778   validateEntryExists("get",name_in,foundEntry);
00779   return *foundEntry;
00780 }
00781 
00782 inline
00783 ParameterEntry*
00784 ParameterList::getEntryPtr(const std::string& name_in)
00785 {
00786   Map::iterator i = params_.find(name_in);
00787   if ( i == params_.end() )
00788     return NULL;
00789   return &entry(i);
00790 }
00791 
00792 inline
00793 const ParameterEntry*
00794 ParameterList::getEntryPtr(const std::string& name_in) const
00795 {
00796   ConstIterator i = params_.find(name_in);
00797   if ( i == params_.end() )
00798     return NULL;
00799   return &entry(i);
00800 }
00801 
00802 // Attribute Functions
00803 
00804 inline
00805 const std::string& ParameterList::name() const
00806 {
00807   return name_;
00808 }
00809   
00810 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00811 template<typename T>
00812 bool ParameterList::isType(const std::string& name_in, T* /*ptr*/) const
00813 {
00814   ConstIterator i = params_.find(name_in);
00815   // If parameter doesn't exist, return false.
00816   if (i == params_.end()) 
00817     return false;
00818   return entry(i).getAny().type() == typeid(T);
00819 }
00820 #endif
00821   
00822 template<typename T>
00823 bool ParameterList::isType(const std::string& name_in) 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 
00832 
00833 // private
00834 
00835 
00836 template<typename T>
00837 inline
00838 void ParameterList::validateEntryType(
00839   const std::string &/*funcName*/, const std::string &name_in,
00840   const ParameterEntry &entry_in
00841   ) const
00842 {
00843   TEST_FOR_EXCEPTION_PURE_MSG(
00844     entry_in.getAny().type() != typeid(T), Exceptions::InvalidParameterType
00845     ,"Error!  An attempt was made to access parameter \""<<name_in<<"\""
00846     " of type \""<<entry_in.getAny().typeName()<<"\""
00847     "\nin the parameter (sub)list \""<<this->name()<<"\""
00848     "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00849     );
00850 }
00851 
00852 // //////////////////////////////////////
00853 // Helper functions
00854   
00861 template<typename T>
00862 T& getParameter( ParameterList& l, const std::string& name )
00863 {
00864   return l.template get<T>(name);
00865 }
00866   
00872 template<typename T>
00873 inline
00874 T& get( ParameterList& l, const std::string& name )
00875 {
00876   return getParameter<T>(l,name);
00877 }
00878   
00885 template<typename T>
00886 const T& getParameter( const ParameterList& l, const std::string& name )
00887 {
00888   return l.template get<T>(name);
00889 }
00890   
00898 template<typename T>
00899 inline
00900 T* getParameterPtr( ParameterList& l, const std::string& name )
00901 {
00902   return l.template getPtr<T>(name);
00903 }
00904   
00912 template<typename T>
00913 inline
00914 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00915 {
00916   return l.template getPtr<T>(name);
00917 }
00918   
00925 template<typename T>
00926 inline
00927 bool isParameterType( ParameterList& l, const std::string& name )
00928 {
00929   return l.isType( name, (T*)NULL );
00930 }
00931   
00938 template<typename T>
00939 inline
00940 bool isParameterType( const ParameterList& l, const std::string& name )
00941 {
00942   return l.isType( name, (T*)NULL );
00943 }
00944   
00956 template<typename T>
00957 void setStringParameterFromArray(
00958   const std::string          &paramName
00959   ,const Array<T>       &array
00960   ,ParameterList        *paramList
00961   )
00962 {
00963   TEST_FOR_EXCEPT(!paramList);
00964   paramList->set(paramName,toString(array));
00965 }
00966   
01031 template<typename T>
01032 Array<T> getArrayFromStringParameter(
01033   const ParameterList   &paramList
01034   ,const std::string         &paramName
01035   ,const int            arrayDim        = -1
01036   ,const bool           mustExist       = true
01037   )
01038 {
01039   std::string arrayStr;
01040   if(mustExist) {
01041     arrayStr = getParameter<std::string>(paramList,paramName);
01042   }
01043   else {
01044     const std::string
01045       *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01046     if(arrayStrPtr) {
01047       arrayStr = *arrayStrPtr;
01048     }
01049     else {
01050       return Array<T>(); // Return an empty array
01051     }
01052   }
01053   Array<T> a;
01054   try {
01055     a = fromStringToArray<T>(arrayStr);
01056   }
01057   catch( const InvalidArrayStringRepresentation&) {
01058     TEST_FOR_EXCEPTION_PURE_MSG(
01059       true, Exceptions::InvalidParameterValue
01060       ,"Error!  The parameter \""<<paramName<<"\"\n"
01061       "in the sublist \""<<paramList.name()<<"\"\n"
01062       "exists, but the std::string value:\n"
01063       "----------\n"
01064       <<arrayStr<<
01065       "\n----------\n"
01066       "is not a valid array represntation!"
01067       );
01068   }
01069   TEST_FOR_EXCEPTION_PURE_MSG(
01070     ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01071     ,Exceptions::InvalidParameterValue
01072     ,"Error!  The parameter \""<<paramName<<"\"\n"
01073     "in the sublist \""<<paramList.name()<<"\"\n"
01074     "exists and is a valid array, but the dimension of\n"
01075     "the read in array a.size() = " << a.size() << "\n"
01076     "was not equal to the expected size arrayDim = " << arrayDim << "!"
01077     );
01078   return a;
01079 }
01080 
01084 inline
01085 RCP<ParameterList> sublist(
01086   const RCP<ParameterList> &paramList, const std::string& name, bool mustAlreadyExist = false
01087   )
01088 {
01089   return rcpWithEmbeddedObjPostDestroy(
01090     &paramList->sublist(name,mustAlreadyExist), paramList, false );
01091 }
01092 
01096 inline
01097 RCP<const ParameterList> sublist(
01098   const RCP<const ParameterList> &paramList, const std::string& name
01099   )
01100 {
01101   return rcpWithEmbeddedObjPostDestroy(
01102     &paramList->sublist(name), paramList, false );
01103 }
01104   
01108 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01109 {
01110   return l.print(os);
01111 }
01112   
01113 } // end of Teuchos namespace
01114 
01115 #endif
01116 
01117 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:44 2011 for Teuchos - Trilinos Tools Package by  doxygen 1.6.3