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 static std::string concreteName( const ParameterList& )
00598 { return name(); }
00599 };
00600
00605 bool operator==( const ParameterList& list1, const ParameterList& list2 );
00606
00611 inline
00612 bool operator!=( const ParameterList& list1, const ParameterList& list2 )
00613 {
00614 return !( list1 == list2 );
00615 }
00616
00625 bool haveSameValues( const ParameterList& list1, const ParameterList& list2 );
00626
00627
00628
00629
00630 inline
00631 ParameterList& ParameterList::setName( const std::string &name_in )
00632 {
00633 name_ = name_in;
00634 return *this;
00635 }
00636
00637
00638
00639 template<typename T>
00640 inline
00641 ParameterList& ParameterList::set(
00642 std::string const& name_in, T const& value_in, std::string const& docString_in,
00643 RCP<const ParameterEntryValidator> const& validator_in
00644 )
00645 {
00646 ParameterEntry &foundEntry = params_[name_in];
00647 foundEntry.setValue(value_in,false,docString_in,validator_in);
00648
00649
00650 if(foundEntry.validator().get())
00651 foundEntry.validator()->validate(foundEntry,name_in,this->name());
00652 return *this;
00653 }
00654
00655 inline
00656 ParameterList& ParameterList::set(
00657 std::string const& name_in, char value[], std::string const& docString
00658 ,RCP<const ParameterEntryValidator> const& validator
00659 )
00660 { return set( name_in, std::string(value), docString, validator ); }
00661
00662 inline
00663 ParameterList& ParameterList::set(
00664 const std::string& name_in, const char value[], const std::string &docString
00665 ,RCP<const ParameterEntryValidator> const& validator
00666 )
00667 { return set( name_in, std::string(value), docString, validator ); }
00668
00669 inline
00670 ParameterList& ParameterList::set(
00671 std::string const& name_in, ParameterList const& value, std::string const&
00672 )
00673 {
00674 sublist(name_in) = value;
00675 return *this;
00676 }
00677
00678 inline
00679 ParameterList& ParameterList::setEntry(std::string const& name_in, ParameterEntry const& entry_in)
00680 {
00681 params_[name_in] = entry_in;
00682 return *this;
00683 }
00684
00685
00686
00687 template<typename T>
00688 T& ParameterList::get(const std::string& name_in, T def_value)
00689 {
00690 ConstIterator i = params_.find(name_in);
00691
00692
00693 if (i == params_.end()) {
00694 params_[name_in].setValue(def_value, true);
00695 i = params_.find(name_in);
00696 } else {
00697
00698 this->template validateEntryType<T>("get", name_in, entry(i));
00699 }
00700
00701
00702 return getValue<T>(entry(i));
00703 }
00704
00705 inline
00706 std::string& ParameterList::get(const std::string& name_in, char def_value[])
00707 { return get(name_in, std::string(def_value)); }
00708
00709 inline
00710 std::string& ParameterList::get(const std::string& name_in, const char def_value[])
00711 { return get(name_in, std::string(def_value)); }
00712
00713 template<typename T>
00714 T& ParameterList::get(const std::string& name_in)
00715 {
00716 ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00717 validateEntryExists("get",name_in,foundEntry);
00718 this->template validateEntryType<T>("get",name_in,*foundEntry);
00719 return getValue<T>(*foundEntry);
00720 }
00721
00722 template<typename T>
00723 const T& ParameterList::get(const std::string& name_in) const
00724 {
00725 const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00726 validateEntryExists("get",name_in,foundEntry);
00727 this->template validateEntryType<T>("get",name_in,*foundEntry);
00728 return getValue<T>(*foundEntry);
00729 }
00730
00731 template<typename T>
00732 inline
00733 T* ParameterList::getPtr(const std::string& name_in)
00734 {
00735 ConstIterator i = params_.find(name_in);
00736 if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00737 return NULL;
00738 return &getValue<T>(entry(i));
00739 }
00740
00741 template<typename T>
00742 inline
00743 const T* ParameterList::getPtr(const std::string& name_in) const
00744 {
00745 ConstIterator i = params_.find(name_in);
00746 if ( i == params_.end() || entry(i).getAny().type() != typeid(T) )
00747 return NULL;
00748 return &getValue<T>(entry(i));
00749 }
00750
00751 inline
00752 ParameterEntry& ParameterList::getEntry(const std::string& name_in)
00753 {
00754 ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00755 validateEntryExists("get",name_in,foundEntry);
00756 return *foundEntry;
00757 }
00758
00759 inline
00760 const ParameterEntry& ParameterList::getEntry(const std::string& name_in) const
00761 {
00762 const ParameterEntry *foundEntry = this->getEntryPtr(name_in);
00763 validateEntryExists("get",name_in,foundEntry);
00764 return *foundEntry;
00765 }
00766
00767 inline
00768 ParameterEntry*
00769 ParameterList::getEntryPtr(const std::string& name_in)
00770 {
00771 Map::iterator i = params_.find(name_in);
00772 if ( i == params_.end() )
00773 return NULL;
00774 return &entry(i);
00775 }
00776
00777 inline
00778 const ParameterEntry*
00779 ParameterList::getEntryPtr(const std::string& name_in) const
00780 {
00781 ConstIterator i = params_.find(name_in);
00782 if ( i == params_.end() )
00783 return NULL;
00784 return &entry(i);
00785 }
00786
00787
00788
00789 inline
00790 const std::string& ParameterList::name() const
00791 {
00792 return name_;
00793 }
00794
00795 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00796 template<typename T>
00797 bool ParameterList::isType(const std::string& name_in, T* ) const
00798 {
00799 ConstIterator i = params_.find(name_in);
00800
00801 if (i == params_.end())
00802 return false;
00803 return entry(i).getAny().type() == typeid(T);
00804 }
00805 #endif
00806
00807 template<typename T>
00808 bool ParameterList::isType(const std::string& name_in) const
00809 {
00810 ConstIterator i = params_.find(name_in);
00811
00812 if (i == params_.end())
00813 return false;
00814 return entry(i).getAny().type() == typeid(T);
00815 }
00816
00817
00818
00819
00820
00821 template<typename T>
00822 inline
00823 void ParameterList::validateEntryType(
00824 const std::string &, const std::string &name_in,
00825 const ParameterEntry &entry_in
00826 ) const
00827 {
00828 TEST_FOR_EXCEPTION_PURE_MSG(
00829 entry_in.getAny().type() != typeid(T), Exceptions::InvalidParameterType
00830 ,"Error! An attempt was made to access parameter \""<<name_in<<"\""
00831 " of type \""<<entry_in.getAny().typeName()<<"\""
00832 "\nin the parameter (sub)list \""<<this->name()<<"\""
00833 "\nusing the incorrect type \""<<TypeNameTraits<T>::name()<<"\"!"
00834 );
00835 }
00836
00837
00838
00839
00846 template<typename T>
00847 T& getParameter( ParameterList& l, const std::string& name )
00848 {
00849 return l.template get<T>(name);
00850 }
00851
00857 template<typename T>
00858 inline
00859 T& get( ParameterList& l, const std::string& name )
00860 {
00861 return getParameter<T>(l,name);
00862 }
00863
00870 template<typename T>
00871 const T& getParameter( const ParameterList& l, const std::string& name )
00872 {
00873 return l.template get<T>(name);
00874 }
00875
00883 template<typename T>
00884 inline
00885 T* getParameterPtr( ParameterList& l, const std::string& name )
00886 {
00887 return l.template getPtr<T>(name);
00888 }
00889
00897 template<typename T>
00898 inline
00899 const T* getParameterPtr( const ParameterList& l, const std::string& name )
00900 {
00901 return l.template getPtr<T>(name);
00902 }
00903
00910 template<typename T>
00911 inline
00912 bool isParameterType( ParameterList& l, const std::string& name )
00913 {
00914 return l.isType( name, (T*)NULL );
00915 }
00916
00923 template<typename T>
00924 inline
00925 bool isParameterType( const ParameterList& l, const std::string& name )
00926 {
00927 return l.isType( name, (T*)NULL );
00928 }
00929
00941 template<typename T>
00942 void setStringParameterFromArray(
00943 const std::string ¶mName
00944 ,const Array<T> &array
00945 ,ParameterList *paramList
00946 )
00947 {
00948 TEST_FOR_EXCEPT(!paramList);
00949 paramList->set(paramName,toString(array));
00950 }
00951
01016 template<typename T>
01017 Array<T> getArrayFromStringParameter(
01018 const ParameterList ¶mList
01019 ,const std::string ¶mName
01020 ,const int arrayDim = -1
01021 ,const bool mustExist = true
01022 )
01023 {
01024 std::string arrayStr;
01025 if(mustExist) {
01026 arrayStr = getParameter<std::string>(paramList,paramName);
01027 }
01028 else {
01029 const std::string
01030 *arrayStrPtr = getParameterPtr<std::string>(paramList,paramName);
01031 if(arrayStrPtr) {
01032 arrayStr = *arrayStrPtr;
01033 }
01034 else {
01035 return Array<T>();
01036 }
01037 }
01038 Array<T> a;
01039 try {
01040 a = fromStringToArray<T>(arrayStr);
01041 }
01042 catch( const InvalidArrayStringRepresentation &except ) {
01043 TEST_FOR_EXCEPTION_PURE_MSG(
01044 true, Exceptions::InvalidParameterValue
01045 ,"Error! The parameter \""<<paramName<<"\"\n"
01046 "in the sublist \""<<paramList.name()<<"\"\n"
01047 "exists, but the std::string value:\n"
01048 "----------\n"
01049 <<arrayStr<<
01050 "\n----------\n"
01051 "is not a valid array represntation!"
01052 );
01053 }
01054 TEST_FOR_EXCEPTION_PURE_MSG(
01055 ( ( a.size()>0 && arrayDim>=0 ) && static_cast<int>(a.size())!=arrayDim )
01056 ,Exceptions::InvalidParameterValue
01057 ,"Error! The parameter \""<<paramName<<"\"\n"
01058 "in the sublist \""<<paramList.name()<<"\"\n"
01059 "exists and is a valid array, but the dimension of\n"
01060 "the read in array a.size() = " << a.size() << "\n"
01061 "was not equal to the expected size arrayDim = " << arrayDim << "!"
01062 );
01063 return a;
01064 }
01065
01069 inline
01070 RCP<ParameterList> sublist(
01071 const RCP<ParameterList> ¶mList, const std::string& name, bool mustAlreadyExist = false
01072 )
01073 {
01074 return rcpWithEmbeddedObjPostDestroy(
01075 ¶mList->sublist(name,mustAlreadyExist), paramList, false );
01076 }
01077
01081 inline
01082 RCP<const ParameterList> sublist(
01083 const RCP<const ParameterList> ¶mList, const std::string& name
01084 )
01085 {
01086 return rcpWithEmbeddedObjPostDestroy(
01087 ¶mList->sublist(name), paramList, false );
01088 }
01089
01093 inline std::ostream& operator<<(std::ostream& os, const ParameterList& l)
01094 {
01095 return l.print(os);
01096 }
01097
01098 }
01099
01100 #endif
01101
01102