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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 
00043 #ifndef TEUCHOS_PARAMETER_LIST_H
00044 #define TEUCHOS_PARAMETER_LIST_H
00045 
00050 #include "Teuchos_ParameterListExceptions.hpp"
00051 #include "Teuchos_ParameterEntry.hpp"
00052 #include "Teuchos_TestForException.hpp"
00053 #include "Teuchos_RCP.hpp"
00054 #include "Teuchos_Array.hpp"
00055 #include "Teuchos_map.hpp"
00056 
00061 namespace Teuchos {
00062 
00066 enum EValidateUsed {
00067   VALIDATE_USED_ENABLED   /*< \brief Validate that parameters in <tt>*this</tt> list
00068                               set using the default value are present in
00069                               the validation list */
00070   ,VALIDATE_USED_DISABLED /*< \brief Do not validate that parameters in <tt>*this</tt> list
00071                               set using the default value are present in
00072                               the validation list */
00073 };
00074 
00078 enum EValidateDefaults {
00079   VALIDATE_DEFAULTS_ENABLED   /*< \brief Validate that parameters in <tt>*this</tt> list
00080                                   set using the default value are present in
00081                                    the validation list */
00082   ,VALIDATE_DEFAULTS_DISABLED /*< \brief Do not validate that parameters in <tt>*this</tt> list
00083                                   set using the default value are present in
00084                                   the validation list */
00085 };
00086 
00100 class TEUCHOS_LIB_DLL_EXPORT ParameterList {
00101 
00103   typedef Teuchos::map<std::string, ParameterEntry> Map;
00104 
00106   typedef Map::iterator Iterator;
00107   
00108 public:
00109 
00111 
00112 
00114   typedef Map::const_iterator ConstIterator;
00115 
00117   class PrintOptions {
00118   public:
00119     PrintOptions() : indent_(0), showTypes_(false), showFlags_(false), showDoc_(false) {}
00120     PrintOptions& indent(int _indent)        { indent_ = _indent; return *this; }
00121     PrintOptions& showTypes(bool _showTypes) { showTypes_ = _showTypes; return *this; }
00122     PrintOptions& showFlags(bool _showFlags) { showFlags_ = _showFlags; return *this; }
00123     PrintOptions& showDoc(bool _showDoc)     { showDoc_ = _showDoc; return *this; }
00124     PrintOptions& incrIndent(int indents)    { indent_ += indents; return *this; }
00125     int indent() const { return indent_; }
00126     bool showTypes() const { return showTypes_; }
00127     bool showFlags() const { return showFlags_; }
00128     bool showDoc() const { return showDoc_; }
00129     PrintOptions copy() const { return PrintOptions(*this); }
00130   private:
00131     int    indent_;
00132     bool   showTypes_;
00133     bool   showFlags_;
00134     bool   showDoc_;
00135   };
00136 
00138   
00140 
00141 
00143   ParameterList();
00144 
00146   ParameterList(const std::string &name);
00147   
00149   ParameterList(const ParameterList& source);
00150   
00152   virtual ~ParameterList();
00153 
00155   
00157 
00158 
00161   ParameterList& setName( const std::string &name );
00162   
00166   ParameterList& operator=(const ParameterList& source);
00167   
00175   ParameterList& setParameters(const ParameterList& source);
00176   
00186   ParameterList& setParametersNotAlreadySet(const ParameterList& source);
00187 
00195   ParameterList& disableRecursiveValidation();
00196   
00205   template<typename T>
00206   ParameterList& set(
00207     std::string const& name, T const& value, std::string const& docString = ""
00208     ,RCP<const ParameterEntryValidator> const& validator = null
00209     );
00210 
00214   ParameterList& set(
00215     std::string const& name, char value[], std::string const& docString = ""
00216     ,RCP<const ParameterEntryValidator> const& validator = null
00217     );
00218 
00222   ParameterList& set(
00223     std::string const& name, const char value[], std::string const& docString = ""
00224     ,RCP<const ParameterEntryValidator> const& validator = null
00225     );
00226 
00229   ParameterList& set(
00230     std::string const& name, ParameterList const& value, std::string const& docString = ""
00231     );
00232 
00237   ParameterList& setEntry(const std::string& name, const ParameterEntry& entry);
00238 
00240   
00242 
00243   
00254   template<typename T>
00255   T& get(const std::string& name, T def_value);
00256 
00260   std::string& get(const std::string& name, char def_value[]);
00261   
00265   std::string& get(const std::string& name, const char def_value[]);
00266   
00274   template<typename T>
00275   T& get(const std::string& name);
00276   
00284   template<typename T>
00285   const T& get(const std::string& name) const;  
00286   
00292   template<typename T>
00293   inline
00294   T* getPtr(const std::string& name);
00295   
00301   template<typename T>
00302   inline
00303   const T* getPtr(const std::string& name) const;  
00304   
00310   ParameterEntry& getEntry(const std::string& name);  
00311   
00317   inline
00318   const ParameterEntry& getEntry(const std::string& name) const;  
00319   
00322   inline
00323   ParameterEntry* getEntryPtr(const std::string& name);  
00324   
00327   inline
00328   const ParameterEntry* getEntryPtr(const std::string& name) const;  
00329 
00332   inline RCP<ParameterEntry> getEntryRCP(const std::string& name);  
00333   
00336   inline RCP<const ParameterEntry> getEntryRCP(const std::string& name) const;
00337 
00339 
00341 
00342  
00356   bool remove(
00357     std::string const& name, bool throwIfNotExists = true
00358     );
00359 
00361   
00363 
00364 
00370   ParameterList& sublist(
00371     const std::string& name, bool mustAlreadyExist = false
00372     ,const std::string& docString = ""
00373     );
00374   
00379   const ParameterList& sublist(const std::string& name) const;
00380 
00382   
00384 
00385 
00387   const std::string& name() const;
00388 
00394   bool isParameter(const std::string& name) const;
00395   
00401   bool isSublist(const std::string& name) const;
00402   
00409   template<typename T>
00410   bool isType(const std::string& name) const;
00411 
00412 #ifndef DOXYGEN_SHOULD_SKIP_THIS  
00413 
00423   template<typename T>
00424   bool isType(const std::string& name, T* ptr) const;
00425 #endif
00426 
00428   
00430 
00431 
00437   void print() const;
00438 
00441   std::ostream& print(std::ostream& os, const PrintOptions &printOptions) const;
00442 
00445   std::ostream& print(std::ostream& os, int indent = 0, bool showTypes = false, bool showFlags = true ) const;
00446   
00448   void unused(std::ostream& os) const;
00449 
00451   std::string currentParametersString() const;
00452 
00454 
00456 
00457 
00459   ConstIterator begin() const ;
00460 
00462   ConstIterator end() const ;
00463 
00465   const ParameterEntry& entry(ConstIterator i) const;
00466   
00468   const std::string& name(ConstIterator i) const;
00469 
00471 
00473 
00474 
00519   void validateParameters(
00520     ParameterList const& validParamList,
00521     int const depth = 1000,
00522     EValidateUsed const validateUsed = VALIDATE_USED_ENABLED,
00523     EValidateDefaults const validateDefaults = VALIDATE_DEFAULTS_ENABLED
00524     ) const;
00525 
00563   void validateParametersAndSetDefaults(
00564     ParameterList const& validParamList,
00565     int const depth = 1000
00566     );
00567 
00569   
00570 private: // Functions
00571  
00573   Iterator nonconstBegin();
00575   Iterator nonconstEnd();
00577   ParameterEntry& entry(Iterator i);
00579   void validateEntryExists( const std::string &funcName, const std::string &name, const ParameterEntry *entry ) const;
00581   template<typename T>
00582   void validateEntryType( const std::string &funcName, const std::string &name, const ParameterEntry &entry ) const;
00584   void updateSubListNames(int depth = 0);
00585   
00586 private: // Data members
00587 
00589   std::string name_;
00590 
00592 //use pragmas to disable some false-positive warnings for windows sharedlibs export
00593 #ifdef _MSC_VER
00594 #pragma warning(push)
00595 #pragma warning(disable:4251)
00596 #endif
00597   Map params_;
00598 #ifdef _MSC_VER
00599 #pragma warning(pop)
00600 #endif
00601 
00603   bool disableRecursiveValidation_;
00604 
00605 };
00606 
00607 
00612 inline
00613 RCP<ParameterList> parameterList()
00614 {
00615   return rcp(new ParameterList);
00616 }
00617 
00618 
00623 inline
00624 RCP<ParameterList> parameterList(const std::string &name)
00625 {
00626   return rcp(new ParameterList(name));
00627 }
00628   
00629 
00634 inline
00635 RCP<ParameterList> parameterList(const ParameterList& source)
00636 {
00637   return rcp(new ParameterList(source));
00638 }
00639 
00640 
00645 template<>
00646 class TEUCHOS_LIB_DLL_EXPORT TypeNameTraits<ParameterList> {
00647 public:
00648   static std::string name() { return "ParameterList"; }
00649   static std::string concreteName( const ParameterList& /*t2*/ )
00650     { return name(); }
00651 };
00652 
00657 TEUCHOS_LIB_DLL_EXPORT bool operator==( const ParameterList& list1, const ParameterList& list2 );
00658 
00663 inline
00664 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00665 {
00666   return !( list1 == list2 );
00667 }
00668 
00677 TEUCHOS_LIB_DLL_EXPORT bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00678 
00679 
00680 // /////////////////////////////////////////////////////
00681 // Inline and Template Function Definitions
00682 
00683 
00684 inline
00685 ParameterList& ParameterList::setName( const std::string &name_in )
00686 {
00687   name_ = name_in;
00688   return *this;
00689 }
00690 
00691 // Set functions
00692 
00693 template<typename T>
00694 inline
00695 ParameterList& ParameterList::set(
00696   std::string const& name_in, T const& value_in, std::string const& docString_in,
00697   RCP<const ParameterEntryValidator> const& validator_in
00698   )
00699 {
00700   ParameterEntry &foundEntry = params_[name_in]; // Will add the entry if not exists
00701   foundEntry.setValue(value_in,false,docString_in,validator_in);
00702   // Validate the value *after* you set it.  It is important to use
00703   // entry.validator() instead of validator since validator might be null!
00704   if(foundEntry.validator().get())
00705     foundEntry.validator()->validate(foundEntry,name_in,this->name());
00706   return *this;
00707 }
00708 
00709 inline
00710 ParameterList& ParameterList::set(
00711   std::string const& name_in, char value[], std::string const& docString
00712   ,RCP<const ParameterEntryValidator> const& validator
00713   ) 
00714 { return set( name_in, std::string(value), docString, validator ); }
00715 
00716 inline
00717 ParameterList& ParameterList::set(
00718   const std::string& name_in, const char value[], const std::string &docString
00719   ,RCP<const ParameterEntryValidator> const& validator
00720   ) 
00721 { return set( name_in, std::string(value), docString, validator ); }
00722 
00723 inline
00724 ParameterList& ParameterList::set(
00725   std::string const& name_in, ParameterList const& value, std::string const& /*docString*/
00726   )
00727 {
00728   sublist(name_in) = value;
00729   return *this;
00730 }
00731 
00732 inline
00733 ParameterList& ParameterList::setEntry(std::string const& name_in, ParameterEntry const& entry_in)
00734 {
00735   params_[name_in] = entry_in;
00736   return *this;
00737 }
00738 
00739 // Get functions
00740 
00741 template<typename T>
00742 T& ParameterList::get(const std::string& name_in, T def_value)
00743 {
00744   ConstIterator i = params_.find(name_in);
00745     
00746   // The parameter was not found, add it to the list
00747   if (i == params_.end()) {
00748     params_[name_in].setValue(def_value, true);
00749     i = params_.find(name_in);
00750   } else {
00751     // The parameter was found, make sure it is the same type as T.
00752     this->template validateEntryType<T>("get", name_in, entry(i));
00753   }
00754 
00755   // Return the value of the parameter
00756   return getValue<T>(entry(i));
00757 }
00758 
00759 inline
00760 std::string& ParameterList::get(const std::string& name_in, char def_value[])
00761 { return get(name_in, std::string(def_value)); }
00762 
00763 inline
00764 std::string& ParameterList::get(const std::string& name_in, const char def_value[])
00765 { return get(name_in, std::string(def_value)); }
00766 
00767 template<typename T>
00768 T& ParameterList::get(const std::string& name_in) 
00769 {
00770   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00771   validateEntryExists("get",name_in,foundEntry);
00772   this->template validateEntryType<T>("get",name_in,*foundEntry);
00773   return getValue<T>(*foundEntry);
00774 }
00775   
00776 template<typename T>
00777 const T& ParameterList::get(const std::string& name_in) const
00778 {
00779   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00780   validateEntryExists("get",name_in,foundEntry);
00781   this->template validateEntryType<T>("get",name_in,*foundEntry);
00782   return getValue<T>(*foundEntry);
00783 }
00784 
00785 template<typename T>
00786 inline
00787 T* ParameterList::getPtr(const std::string& name_in) 
00788 {
00789   ConstIterator i = params_.find(name_in);
00790   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00791     return NULL;
00792   return &getValue<T>(entry(i));
00793 }
00794   
00795 template<typename T>
00796 inline
00797 const T* ParameterList::getPtr(const std::string& name_in) const
00798 {
00799   ConstIterator i = params_.find(name_in);
00800   if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00801     return NULL;
00802   return &getValue<T>(entry(i));
00803 }
00804 
00805 inline
00806 ParameterEntry& ParameterList::getEntry(const std::string& name_in)
00807 {
00808   ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00809   validateEntryExists("get",name_in,foundEntry);
00810   return *foundEntry;
00811 }
00812   
00813 inline
00814 const ParameterEntry& ParameterList::getEntry(const std::string& name_in) const
00815 {
00816   const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00817   validateEntryExists("get",name_in,foundEntry);
00818   return *foundEntry;
00819 }
00820 
00821 inline
00822 ParameterEntry*
00823 ParameterList::getEntryPtr(const std::string& name_in)
00824 {
00825   Map::iterator i = params_.find(name_in);
00826   if ( i == params_.end() )
00827     return NULL;
00828   return &entry(i);
00829 }
00830 
00831 inline
00832 const ParameterEntry*
00833 ParameterList::getEntryPtr(const std::string& name_in) const
00834 {
00835   ConstIterator i = params_.find(name_in);
00836   if ( i == params_.end() )
00837     return NULL;
00838   return &entry(i);
00839 }
00840 
00841 inline RCP<ParameterEntry>
00842 ParameterList::getEntryRCP(const std::string& name_in)
00843 {
00844   Iterator i = params_.find(name_in);
00845   if ( i == params_.end() )
00846     return null;
00847   return rcpFromRef(entry(i));
00848 }
00849 
00850 inline RCP<const ParameterEntry>
00851 ParameterList::getEntryRCP(const std::string& name_in) const
00852 {
00853   ConstIterator i = params_.find(name_in);
00854   if ( i == params_.end() )
00855     return null;
00856   return rcpFromRef(entry(i));
00857 }
00858 
00859 // Attribute Functions
00860 
00861 inline
00862 const std::string& ParameterList::name() const
00863 {
00864   return name_;
00865 }
00866   
00867 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00868 template<typename T>
00869 bool ParameterList::isType(const std::string& name_in, T* /*ptr*/) const
00870 {
00871   ConstIterator i = params_.find(name_in);
00872   // If parameter doesn't exist, return false.
00873   if (i == params_.end()) 
00874     return false;
00875   return entry(i).getAny().type() == typeid(T);
00876 }
00877 #endif
00878   
00879 template<typename T>
00880 bool ParameterList::isType(const std::string& name_in) const
00881 {
00882   ConstIterator i = params_.find(name_in);
00883   // If parameter doesn't exist, return false.
00884   if (i == params_.end()) 
00885     return false;
00886   return entry(i).getAny().type() == typeid(T);
00887 }
00888 
00889 
00890 // private
00891 
00892 
00893 template<typename T>
00894 inline
00895 void ParameterList::validateEntryType(
00896   const std::string &/*funcName*/, const std::string &name_in,
00897   const ParameterEntry &entry_in
00898   ) const
00899 {
00900   TEST_FOR_EXCEPTION_PURE_MSG(
00901     entry_in.getAny().type() != typeid(T), Exceptions::InvalidParameterType
00902     ,"Error!  An attempt was made to access parameter \""<<name_in<<"\""
00903     " of type \""<<entry_in.getAny().typeName()<<"\""
00904     "\nin the parameter (sub)list \""<<this->name()<<"\""
00905     "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00906     );
00907 }
00908 
00909 // //////////////////////////////////////
00910 // Helper functions
00911   
00918 template<typename T>
00919 T& getParameter( ParameterList& l, const std::string& name )
00920 {
00921   return l.template get<T>(name);
00922 }
00923   
00929 template<typename T>
00930 inline
00931 T& get( ParameterList& l, const std::string& name )
00932 {
00933   return getParameter<T>(l,name);
00934 }
00935   
00942 template<typename T>
00943 const T& getParameter( const ParameterList& l, const std::string& name )
00944 {
00945   return l.template get<T>(name);
00946 }
00947   
00955 template<typename T>
00956 inline
00957 T* getParameterPtr( ParameterList& l, const std::string& name )
00958 {
00959   return l.template getPtr<T>(name);
00960 }
00961   
00969 template<typename T>
00970 inline
00971 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00972 {
00973   return l.template getPtr<T>(name);
00974 }
00975   
00982 template<typename T>
00983 inline
00984 bool isParameterType( ParameterList& l, const std::string& name )
00985 {
00986   return l.isType( name, (T*)NULL );
00987 }
00988   
00995 template<typename T>
00996 inline
00997 bool isParameterType( const ParameterList& l, const std::string& name )
00998 {
00999   return l.isType( name, (T*)NULL );
01000 }
01001   
01013 template<typename T>
01014 void setStringParameterFromArray(
01015   const std::string          &paramName
01016   ,const Array<T>       &array
01017   ,ParameterList        *paramList
01018   )
01019 {
01020   TEST_FOR_EXCEPT(!paramList);
01021   paramList->set(paramName,toString(array));
01022 }
01023   
01088 template<typename T>
01089 Array<T> getArrayFromStringParameter(
01090   const ParameterList   &paramList
01091   ,const std::string         &paramName
01092   ,const int            arrayDim        = -1
01093   ,const bool           mustExist       = true
01094   )
01095 {
01096   std::string arrayStr;
01097   if(mustExist) {
01098     arrayStr = getParameter<std::string>(paramList,paramName);
01099   }
01100   else {
01101     const std::string
01102       *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01103     if(arrayStrPtr) {
01104       arrayStr = *arrayStrPtr;
01105     }
01106     else {
01107       return Array<T>(); // Return an empty array
01108     }
01109   }
01110   Array<T> a;
01111   try {
01112     a = fromStringToArray<T>(arrayStr);
01113   }
01114   catch( const InvalidArrayStringRepresentation&) {
01115     TEST_FOR_EXCEPTION_PURE_MSG(
01116       true, Exceptions::InvalidParameterValue
01117       ,"Error!  The parameter \""<<paramName<<"\"\n"
01118       "in the sublist \""<<paramList.name()<<"\"\n"
01119       "exists, but the std::string value:\n"
01120       "----------\n"
01121       <<arrayStr<<
01122       "\n----------\n"
01123       "is not a valid array represntation!"
01124       );
01125   }
01126   TEST_FOR_EXCEPTION_PURE_MSG(
01127     ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01128     ,Exceptions::InvalidParameterValue
01129     ,"Error!  The parameter \""<<paramName<<"\"\n"
01130     "in the sublist \""<<paramList.name()<<"\"\n"
01131     "exists and is a valid array, but the dimension of\n"
01132     "the read in array a.size() = " << a.size() << "\n"
01133     "was not equal to the expected size arrayDim = " << arrayDim << "!"
01134     );
01135   return a;
01136 }
01137 
01141 inline
01142 RCP<ParameterList> sublist(
01143   const RCP<ParameterList> &paramList, const std::string& name, bool mustAlreadyExist = false
01144   )
01145 {
01146   return rcpWithEmbeddedObjPostDestroy(
01147     &paramList->sublist(name,mustAlreadyExist), paramList, false );
01148 }
01149 
01153 inline
01154 RCP<const ParameterList> sublist(
01155   const RCP<const ParameterList> &paramList, const std::string& name
01156   )
01157 {
01158   return rcpWithEmbeddedObjPostDestroy(
01159     &paramList->sublist(name), paramList, false );
01160 }
01161   
01165 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01166 {
01167   return l.print(os);
01168 }
01169   
01170 } // end of Teuchos namespace
01171 
01172 #endif
01173 
01174 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines