00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00055
00056
00057 ,VALIDATE_USED_DISABLED
00058
00059
00060 };
00061
00065 enum EValidateDefaults {
00066 VALIDATE_DEFAULTS_ENABLED
00067
00068
00069 ,VALIDATE_DEFAULTS_DISABLED
00070
00071
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:
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:
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& )
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
00634
00635 inline
00636 ParameterList& ParameterList::setName( const std::string &name_in )
00637 {
00638 name_ = name_in;
00639 return *this;
00640 }
00641
00642
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];
00652 foundEntry.setValue(value_in,false,docString_in,validator_in);
00653
00654
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&
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
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
00698 if (i == params_.end()) {
00699 params_[name_in].setValue(def_value, true);
00700 i = params_.find(name_in);
00701 } else {
00702
00703 this->template validateEntryType<T>("get", name_in, entry(i));
00704 }
00705
00706
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
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* ) const
00803 {
00804 ConstIterator i = params_.find(name_in);
00805
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
00817 if (i == params_.end())
00818 return false;
00819 return entry(i).getAny().type() == typeid(T);
00820 }
00821
00822
00823
00824
00825
00826 template<typename T>
00827 inline
00828 void ParameterList::validateEntryType(
00829 const std::string &, 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
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 ¶mName
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 ¶mList
01024 ,const std::string ¶mName
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>();
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> ¶mList, const std::string& name, bool mustAlreadyExist = false
01077 )
01078 {
01079 return rcpWithEmbeddedObjPostDestroy(
01080 ¶mList->sublist(name,mustAlreadyExist), paramList, false );
01081 }
01082
01086 inline
01087 RCP<const ParameterList> sublist(
01088 const RCP<const ParameterList> ¶mList, const std::string& name
01089 )
01090 {
01091 return rcpWithEmbeddedObjPostDestroy(
01092 ¶mList->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 }
01104
01105 #endif
01106
01107