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 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:
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:
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 };
00598
00603 bool operator==( const ParameterList& list1, const ParameterList& list2 );
00604
00609 inline
00610 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00611 {
00612 return !( list1 == list2 );
00613 }
00614
00623 bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00624
00625
00626
00627
00628 inline
00629 ParameterList& ParameterList::setName( const std::string &name )
00630 {
00631 name_ = name;
00632 return *this;
00633 }
00634
00635
00636
00637 template<typename T>
00638 inline
00639 ParameterList& ParameterList::set(
00640 std::string const& name, T const& value, std::string const& docString
00641 ,RCP<const ParameterEntryValidator> const& validator
00642 )
00643 {
00644 ParameterEntry &entry = params_[name];
00645 entry.setValue(value,false,docString,validator);
00646
00647
00648 if(entry.validator().get())
00649 entry.validator()->validate(entry,name,this->name());
00650 return *this;
00651 }
00652
00653 inline
00654 ParameterList& ParameterList::set(
00655 std::string const& name, char value[], std::string const& docString
00656 ,RCP<const ParameterEntryValidator> const& validator
00657 )
00658 { return set( name, std::string(value), docString, validator ); }
00659
00660 inline
00661 ParameterList& ParameterList::set(
00662 const std::string& name, const char value[], const std::string &docString
00663 ,RCP<const ParameterEntryValidator> const& validator
00664 )
00665 { return set( name, std::string(value), docString, validator ); }
00666
00667 inline
00668 ParameterList& ParameterList::set(
00669 std::string const& name, ParameterList const& value, std::string const& docString
00670 )
00671 {
00672 sublist(name) = value;
00673 return *this;
00674 }
00675
00676 inline
00677 ParameterList& ParameterList::setEntry(std::string const& name, ParameterEntry const& entry)
00678 {
00679 params_[name] = entry;
00680 return *this;
00681 }
00682
00683
00684
00685 template<typename T>
00686 T& ParameterList::get(const std::string& name, T def_value)
00687 {
00688 ConstIterator i = params_.find(name);
00689
00690
00691 if (i == params_.end()) {
00692 params_[name].setValue(def_value, true);
00693 i = params_.find(name);
00694 } else {
00695
00696 this->template validateEntryType<T>("get",name,entry(i));
00697 }
00698
00699
00700 return getValue<T>(entry(i));
00701 }
00702
00703 inline
00704 std::string& ParameterList::get(const std::string& name, char def_value[])
00705 { return get(name, std::string(def_value)); }
00706
00707 inline
00708 std::string& ParameterList::get(const std::string& name, const char def_value[])
00709 { return get(name, std::string(def_value)); }
00710
00711 template<typename T>
00712 T& ParameterList::get(const std::string& name)
00713 {
00714 ParameterEntry *entry = this->getEntryPtr(name);
00715 validateEntryExists("get",name,entry);
00716 this->template validateEntryType<T>("get",name,*entry);
00717 return getValue<T>(*entry);
00718 }
00719
00720 template<typename T>
00721 const T& ParameterList::get(const std::string& name) const
00722 {
00723 const ParameterEntry *entry = this->getEntryPtr(name);
00724 validateEntryExists("get",name,entry);
00725 this->template validateEntryType<T>("get",name,*entry);
00726 return getValue<T>(*entry);
00727 }
00728
00729 template<typename T>
00730 inline
00731 T* ParameterList::getPtr(const std::string& name)
00732 {
00733 ConstIterator i = params_.find(name);
00734 if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00735 return NULL;
00736 return &getValue<T>(entry(i));
00737 }
00738
00739 template<typename T>
00740 inline
00741 const T* ParameterList::getPtr(const std::string& name) const
00742 {
00743 ConstIterator i = params_.find(name);
00744 if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00745 return NULL;
00746 return &getValue<T>(entry(i));
00747 }
00748
00749 inline
00750 ParameterEntry& ParameterList::getEntry(const std::string& name)
00751 {
00752 ParameterEntry *entry = this->getEntryPtr(name);
00753 validateEntryExists("get",name,entry);
00754 return *entry;
00755 }
00756
00757 inline
00758 const ParameterEntry& ParameterList::getEntry(const std::string& name) const
00759 {
00760 const ParameterEntry *entry = this->getEntryPtr(name);
00761 validateEntryExists("get",name,entry);
00762 return *entry;
00763 }
00764
00765 inline
00766 ParameterEntry*
00767 ParameterList::getEntryPtr(const std::string& name)
00768 {
00769 Map::iterator i = params_.find(name);
00770 if ( i == params_.end() )
00771 return NULL;
00772 return &entry(i);
00773 }
00774
00775 inline
00776 const ParameterEntry*
00777 ParameterList::getEntryPtr(const std::string& name) const
00778 {
00779 ConstIterator i = params_.find(name);
00780 if ( i == params_.end() )
00781 return NULL;
00782 return &entry(i);
00783 }
00784
00785
00786
00787 inline
00788 const std::string& ParameterList::name() const
00789 {
00790 return name_;
00791 }
00792
00793 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00794 template<typename T>
00795 bool ParameterList::isType(const std::string& name, T* ptr) const
00796 {
00797 ConstIterator i = params_.find(name);
00798
00799 if (i == params_.end())
00800 return false;
00801 return entry(i).getAny().type() == typeid(T);
00802 }
00803 #endif
00804
00805 template<typename T>
00806 bool ParameterList::isType(const std::string& name) const
00807 {
00808 ConstIterator i = params_.find(name);
00809
00810 if (i == params_.end())
00811 return false;
00812 return entry(i).getAny().type() == typeid(T);
00813 }
00814
00815
00816
00817
00818
00819 template<typename T>
00820 inline
00821 void ParameterList::validateEntryType(
00822 const std::string &funcName, const std::string &name,
00823 const ParameterEntry &entry
00824 ) const
00825 {
00826 TEST_FOR_EXCEPTION_PURE_MSG(
00827 (entry.getAny().type() != typeid(T))
00828 && (entry.getAny().typeName() != TypeNameTraits<T>::name())
00829 , Exceptions::InvalidParameterType
00830 ,"Error! An attempt was made to access parameter \""<<name<<"\""
00831 " of type \""<<entry.getAny().typeName()<<"\""
00832 "\nin the parameter (sub)list \""<<this->name()<<"\""
00833 "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00834 );
00835
00836
00837
00838
00839
00840
00841 }
00842
00843
00844
00845
00852 template<typename T>
00853 T& getParameter( ParameterList& l, const std::string& name )
00854 {
00855 return l.template get<T>(name);
00856 }
00857
00863 template<typename T>
00864 inline
00865 T& get( ParameterList& l, const std::string& name )
00866 {
00867 return getParameter<T>(l,name);
00868 }
00869
00876 template<typename T>
00877 const T& getParameter( const ParameterList& l, const std::string& name )
00878 {
00879 return l.template get<T>(name);
00880 }
00881
00889 template<typename T>
00890 inline
00891 T* getParameterPtr( ParameterList& l, const std::string& name )
00892 {
00893 return l.template getPtr<T>(name);
00894 }
00895
00903 template<typename T>
00904 inline
00905 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00906 {
00907 return l.template getPtr<T>(name);
00908 }
00909
00916 template<typename T>
00917 inline
00918 bool isParameterType( ParameterList& l, const std::string& name )
00919 {
00920 return l.isType( name, (T*)NULL );
00921 }
00922
00929 template<typename T>
00930 inline
00931 bool isParameterType( const ParameterList& l, const std::string& name )
00932 {
00933 return l.isType( name, (T*)NULL );
00934 }
00935
00947 template<typename T>
00948 void setStringParameterFromArray(
00949 const std::string ¶mName
00950 ,const Array<T> &array
00951 ,ParameterList *paramList
00952 )
00953 {
00954 TEST_FOR_EXCEPT(!paramList);
00955 paramList->set(paramName,toString(array));
00956 }
00957
01022 template<typename T>
01023 Array<T> getArrayFromStringParameter(
01024 const ParameterList ¶mList
01025 ,const std::string ¶mName
01026 ,const int arrayDim = -1
01027 ,const bool mustExist = true
01028 )
01029 {
01030 std::string arrayStr;
01031 if(mustExist) {
01032 arrayStr = getParameter<std::string>(paramList,paramName);
01033 }
01034 else {
01035 const std::string
01036 *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01037 if(arrayStrPtr) {
01038 arrayStr = *arrayStrPtr;
01039 }
01040 else {
01041 return Array<T>();
01042 }
01043 }
01044 Array<T> a;
01045 try {
01046 a = fromStringToArray<T>(arrayStr);
01047 }
01048 catch( const InvalidArrayStringRepresentation &except ) {
01049 TEST_FOR_EXCEPTION_PURE_MSG(
01050 true, Exceptions::InvalidParameterValue
01051 ,"Error! The parameter \""<<paramName<<"\"\n"
01052 "in the sublist \""<<paramList.name()<<"\"\n"
01053 "exists, but the std::string value:\n"
01054 "----------\n"
01055 <<arrayStr<<
01056 "\n----------\n"
01057 "is not a valid array represntation!"
01058 );
01059 }
01060 TEST_FOR_EXCEPTION_PURE_MSG(
01061 ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01062 ,Exceptions::InvalidParameterValue
01063 ,"Error! The parameter \""<<paramName<<"\"\n"
01064 "in the sublist \""<<paramList.name()<<"\"\n"
01065 "exists and is a valid array, but the dimension of\n"
01066 "the read in array a.size() = " << a.size() << "\n"
01067 "was not equal to the expected size arrayDim = " << arrayDim << "!"
01068 );
01069 return a;
01070 }
01071
01075 inline
01076 RCP<ParameterList> sublist(
01077 const RCP<ParameterList> ¶mList, const std::string& name, bool mustAlreadyExist = false
01078 )
01079 {
01080 RCP<ParameterList>
01081 sublist = Teuchos::rcp(¶mList->sublist(name,mustAlreadyExist),false);
01082 set_extra_data(paramList,"masterParamList",&sublist);
01083 return sublist;
01084 }
01085
01089 inline
01090 RCP<const ParameterList> sublist(
01091 const RCP<const ParameterList> ¶mList, const std::string& name
01092 )
01093 {
01094 RCP<const ParameterList>
01095 sublist = Teuchos::rcp(¶mList->sublist(name),false);
01096 set_extra_data(paramList,"masterParamList",&sublist);
01097 return sublist;
01098 }
01099
01103 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01104 {
01105 return l.print(os);
01106 }
01107
01108 }
01109
01110 #endif
01111
01112