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   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_;
00563   Map params_;
00565   bool disableRecursiveValidation_;
00566 
00567 };
00568 
00569 
00571 inline
00572 RCP<ParameterList> parameterList()
00573 {
00574   return rcp(new ParameterList);
00575 }
00576 
00577 
00579 inline
00580 RCP<ParameterList> parameterList(const std::string &name)
00581 {
00582   return rcp(new ParameterList(name));
00583 }
00584   
00586 inline
00587 RCP<ParameterList> parameterList(const ParameterList& source)
00588 {
00589   return rcp(new ParameterList(source));
00590 }
00591 
00592 
00593 
00598 template<>
00599 class TypeNameTraits<ParameterList> {
00600 public:
00601   static std::string name() { return "ParameterList"; }
00602   static std::string concreteName( const ParameterList& /*t2*/ )
00603     { return name(); }
00604 };
00605 
00610 bool operator==( const ParameterList& list1, const ParameterList& list2 );
00611 
00616 inline
00617 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00618 {
00619   return !( list1 == list2 );
00620 }
00621 
00630 bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00631 
00632 // /////////////////////////////////////////////////////
00633 // Inline and Template Function Definitions
00634 
00635 inline
00636 ParameterList& ParameterList::setName( const std::string &name_in )
00637 {
00638   name_ = name_in;
00639   return *this;
00640 }
00641 
00642 // Set functions
00643 
00644 template<typename T>
00645 inline
00646 ParameterList& ParameterList::set(
00647   std::string const& name_in, T const& value_in, std::string const& docString_in,
00648   RCP<const ParameterEntryValidator> const& validator_in
00649   )
00650 {
00651   ParameterEntry &foundEntry = params_[name_in]; // Will add the entry if not exists
00652   foundEntry.setValue(value_in,false,docString_in,validator_in);
00653   // Validate the value *after* you set it.  It is important to use
00654   // entry.validator() instead of validator since validator might be null!
00655   if(foundEntry.validator().get())
00656     foundEntry.validator()->validate(foundEntry,name_in,this->name());
00657   return *this;
00658 }
00659 
00660 inline
00661 ParameterList& ParameterList::set(
00662   std::string const& name_in, char value[], std::string const& docString
00663   ,RCP<const ParameterEntryValidator> const& validator
00664   ) 
00665 { return set( name_in, std::string(value), docString, validator ); }
00666 
00667 inline
00668 ParameterList& ParameterList::set(
00669   const std::string& name_in, const char value[], const std::string &docString
00670   ,RCP<const ParameterEntryValidator> const& validator
00671   ) 
00672 { return set( name_in, std::string(value), docString, validator ); }
00673 
00674 inline
00675 ParameterList& ParameterList::set(
00676   std::string const& name_in, ParameterList const& value, std::string const& /*docString*/
00677   )
00678 {
00679   sublist(name_in) = value;
00680   return *this;
00681 }
00682 
00683 inline
00684 ParameterList& ParameterList::setEntry(std::string const& name_in, ParameterEntry const& entry_in)
00685 {
00686   params_[name_in] = entry_in;
00687   return *this;
00688 }
00689 
00690 // Get functions
00691 
00692 template<typename T>
00693 T& ParameterList::get(const std::string& name_in, T def_value)
00694 {
00695   ConstIterator i = params_.find(name_in);
00696     
00697   // The parameter was not found, add it to the list
00698   if (i == params_.end()) {
00699     params_[name_in].setValue(def_value, true);
00700     i = params_.find(name_in);
00701   } else {
00702     // The parameter was found, make sure it is the same type as T.
00703     this->template validateEntryType<T>("get", name_in, entry(i));
00704   }
00705 
00706   // Return the value of the parameter
00707   return getValue<T>(entry(i));
00708 }
00709 
00710 inline
00711 std::string& ParameterList::get(const std::string& name_in, char def_value[])
00712 { return get(name_in, std::string(def_value)); }
00713 
00714 inline
00715 std::string& ParameterList::get(const std::string& name_in, const char def_value[])
00716 { return get(name_in, std::string(def_value)); }
00717 
00718 template<typename T>
00719 T& ParameterList::get(const std::string& name_in) 
00720 {
00721   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00722   validateEntryExists("get",name_in,foundEntry);
00723   this->template validateEntryType<T>("get",name_in,*foundEntry);
00724   return getValue<T>(*foundEntry);
00725 }
00726   
00727 template<typename T>
00728 const T& ParameterList::get(const std::string& name_in) const
00729 {
00730   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00731   validateEntryExists("get",name_in,foundEntry);
00732   this->template validateEntryType<T>("get",name_in,*foundEntry);
00733   return getValue<T>(*foundEntry);
00734 }
00735 
00736 template<typename T>
00737 inline
00738 T* ParameterList::getPtr(const std::string& name_in) 
00739 {
00740   ConstIterator i = params_.find(name_in);
00741   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00742     return NULL;
00743   return &getValue<T>(entry(i));
00744 }
00745   
00746 template<typename T>
00747 inline
00748 const T* ParameterList::getPtr(const std::string& name_in) const
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 inline
00757 ParameterEntry& ParameterList::getEntry(const std::string& name_in)
00758 {
00759   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00760   validateEntryExists("get",name_in,foundEntry);
00761   return *foundEntry;
00762 }
00763   
00764 inline
00765 const ParameterEntry& ParameterList::getEntry(const std::string& name_in) const
00766 {
00767   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00768   validateEntryExists("get",name_in,foundEntry);
00769   return *foundEntry;
00770 }
00771 
00772 inline
00773 ParameterEntry*
00774 ParameterList::getEntryPtr(const std::string& name_in)
00775 {
00776   Map::iterator i = params_.find(name_in);
00777   if ( i == params_.end() )
00778     return NULL;
00779   return &entry(i);
00780 }
00781 
00782 inline
00783 const ParameterEntry*
00784 ParameterList::getEntryPtr(const std::string& name_in) const
00785 {
00786   ConstIterator i = params_.find(name_in);
00787   if ( i == params_.end() )
00788     return NULL;
00789   return &entry(i);
00790 }
00791 
00792 // Attribute Functions
00793 
00794 inline
00795 const std::string& ParameterList::name() const
00796 {
00797   return name_;
00798 }
00799   
00800 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00801 template<typename T>
00802 bool ParameterList::isType(const std::string& name_in, T* /*ptr*/) const
00803 {
00804   ConstIterator i = params_.find(name_in);
00805   // If parameter doesn't exist, return false.
00806   if (i == params_.end()) 
00807     return false;
00808   return entry(i).getAny().type() == typeid(T);
00809 }
00810 #endif
00811   
00812 template<typename T>
00813 bool ParameterList::isType(const std::string& name_in) const
00814 {
00815   ConstIterator i = params_.find(name_in);
00816   // If parameter doesn't exist, return false.
00817   if (i == params_.end()) 
00818     return false;
00819   return entry(i).getAny().type() == typeid(T);
00820 }
00821 
00822 
00823 // private
00824 
00825 
00826 template<typename T>
00827 inline
00828 void ParameterList::validateEntryType(
00829   const std::string &/*funcName*/, const std::string &name_in,
00830   const ParameterEntry &entry_in
00831   ) const
00832 {
00833   TEST_FOR_EXCEPTION_PURE_MSG(
00834     entry_in.getAny().type() != typeid(T), Exceptions::InvalidParameterType
00835     ,"Error!  An attempt was made to access parameter \""<<name_in<<"\""
00836     " of type \""<<entry_in.getAny().typeName()<<"\""
00837     "\nin the parameter (sub)list \""<<this->name()<<"\""
00838     "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00839     );
00840 }
00841 
00842 // //////////////////////////////////////
00843 // Helper functions
00844   
00851 template<typename T>
00852 T& getParameter( ParameterList& l, const std::string& name )
00853 {
00854   return l.template get<T>(name);
00855 }
00856   
00862 template<typename T>
00863 inline
00864 T& get( ParameterList& l, const std::string& name )
00865 {
00866   return getParameter<T>(l,name);
00867 }
00868   
00875 template<typename T>
00876 const T& getParameter( const ParameterList& l, const std::string& name )
00877 {
00878   return l.template get<T>(name);
00879 }
00880   
00888 template<typename T>
00889 inline
00890 T* getParameterPtr( ParameterList& l, const std::string& name )
00891 {
00892   return l.template getPtr<T>(name);
00893 }
00894   
00902 template<typename T>
00903 inline
00904 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00905 {
00906   return l.template getPtr<T>(name);
00907 }
00908   
00915 template<typename T>
00916 inline
00917 bool isParameterType( ParameterList& l, const std::string& name )
00918 {
00919   return l.isType( name, (T*)NULL );
00920 }
00921   
00928 template<typename T>
00929 inline
00930 bool isParameterType( const ParameterList& l, const std::string& name )
00931 {
00932   return l.isType( name, (T*)NULL );
00933 }
00934   
00946 template<typename T>
00947 void setStringParameterFromArray(
00948   const std::string          &paramName
00949   ,const Array<T>       &array
00950   ,ParameterList        *paramList
00951   )
00952 {
00953   TEST_FOR_EXCEPT(!paramList);
00954   paramList->set(paramName,toString(array));
00955 }
00956   
01021 template<typename T>
01022 Array<T> getArrayFromStringParameter(
01023   const ParameterList   &paramList
01024   ,const std::string         &paramName
01025   ,const int            arrayDim        = -1
01026   ,const bool           mustExist       = true
01027   )
01028 {
01029   std::string arrayStr;
01030   if(mustExist) {
01031     arrayStr = getParameter<std::string>(paramList,paramName);
01032   }
01033   else {
01034     const std::string
01035       *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01036     if(arrayStrPtr) {
01037       arrayStr = *arrayStrPtr;
01038     }
01039     else {
01040       return Array<T>(); // Return an empty array
01041     }
01042   }
01043   Array<T> a;
01044   try {
01045     a = fromStringToArray<T>(arrayStr);
01046   }
01047   catch( const InvalidArrayStringRepresentation&) {
01048     TEST_FOR_EXCEPTION_PURE_MSG(
01049       true, Exceptions::InvalidParameterValue
01050       ,"Error!  The parameter \""<<paramName<<"\"\n"
01051       "in the sublist \""<<paramList.name()<<"\"\n"
01052       "exists, but the std::string value:\n"
01053       "----------\n"
01054       <<arrayStr<<
01055       "\n----------\n"
01056       "is not a valid array represntation!"
01057       );
01058   }
01059   TEST_FOR_EXCEPTION_PURE_MSG(
01060     ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01061     ,Exceptions::InvalidParameterValue
01062     ,"Error!  The parameter \""<<paramName<<"\"\n"
01063     "in the sublist \""<<paramList.name()<<"\"\n"
01064     "exists and is a valid array, but the dimension of\n"
01065     "the read in array a.size() = " << a.size() << "\n"
01066     "was not equal to the expected size arrayDim = " << arrayDim << "!"
01067     );
01068   return a;
01069 }
01070 
01074 inline
01075 RCP<ParameterList> sublist(
01076   const RCP<ParameterList> &paramList, const std::string& name, bool mustAlreadyExist = false
01077   )
01078 {
01079   return rcpWithEmbeddedObjPostDestroy(
01080     &paramList->sublist(name,mustAlreadyExist), paramList, false );
01081 }
01082 
01086 inline
01087 RCP<const ParameterList> sublist(
01088   const RCP<const ParameterList> &paramList, const std::string& name
01089   )
01090 {
01091   return rcpWithEmbeddedObjPostDestroy(
01092     &paramList->sublist(name), paramList, false );
01093 }
01094   
01098 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01099 {
01100   return l.print(os);
01101 }
01102   
01103 } // end of Teuchos namespace
01104 
01105 #endif
01106 
01107 

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