Teuchos - Trilinos Tools Package Version of the Day
Teuchos_ParameterList.cpp
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 //#define TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00043 
00044 #include "Teuchos_ParameterList.hpp"
00045 #include "Teuchos_FancyOStream.hpp"
00046 #include "Teuchos_StrUtils.hpp"
00047 #include "Teuchos_VerboseObject.hpp"
00048 
00049 
00050 namespace {
00051 
00052 
00053 std::string filterValueToString(const Teuchos::ParameterEntry& entry )
00054 {
00055   return ( entry.isList() ? std::string("...") : toString(entry.getAny()) );
00056 }
00057 
00058 
00059 struct ListPlusValidList {
00060   Teuchos::ParameterList   *list;
00061   Teuchos::ParameterList   *validList;
00062   ListPlusValidList(
00063     Teuchos::ParameterList   *_list
00064     ,Teuchos::ParameterList  *_validList
00065     )
00066     :list(_list),validList(_validList)
00067     {}
00068 };
00069 
00070 
00071 } // namespace 
00072 
00073 
00074 namespace Teuchos {
00075 
00076 
00077 // Constructors/Destructor/Info
00078 
00079 
00080 ParameterList::ParameterList()
00081   :name_("ANONYMOUS"), disableRecursiveValidation_(false)
00082 {}
00083 
00084 
00085 ParameterList::ParameterList(const std::string &name_in)
00086   :name_(name_in), disableRecursiveValidation_(false)
00087 {}
00088 
00089 
00090 ParameterList::ParameterList(const ParameterList& source)
00091 {
00092   name_ = source.name_;
00093   params_ = source.params_;
00094   disableRecursiveValidation_ = source.disableRecursiveValidation_;
00095 }
00096 
00097 
00098 ParameterList::~ParameterList() 
00099 {}
00100 
00101 
00102 Ordinal ParameterList::numParams() const
00103 {
00104   return params_.numObjects();
00105 }
00106 
00107 
00108 ParameterList& ParameterList::operator=(const ParameterList& source) 
00109 {
00110   if (&source == this)
00111     return *this;
00112   name_ = source.name_;
00113   params_ = source.params_;
00114   disableRecursiveValidation_ = source.disableRecursiveValidation_;
00115   return *this;
00116 }
00117 
00118 
00119 ParameterList& ParameterList::setParameters(const ParameterList& source)
00120 {
00121   for( ConstIterator i = source.begin(); i != source.end(); ++i ) {
00122     const std::string &name_i = this->name(i);
00123     const ParameterEntry &entry_i = this->entry(i);
00124     if(entry_i.isList()) {
00125       this->sublist(name_i,false,entry_i.docString()).setParameters(
00126         getValue<ParameterList>(entry_i) );
00127     }
00128     else {
00129       this->setEntry(name_i,entry_i);
00130     }
00131   }
00132   this->updateSubListNames();
00133   return *this;
00134 }
00135 
00136 
00137 ParameterList& ParameterList::setParametersNotAlreadySet(
00138   const ParameterList& source
00139   ) 
00140 {
00141   for( ConstIterator i = source.begin(); i != source.end(); ++i ) {
00142     const std::string &name_i = this->name(i);
00143     const ParameterEntry &entry_i = this->entry(i);
00144     if(entry_i.isList()) {
00145       this->sublist(name_i,false,entry_i.docString()).setParametersNotAlreadySet(
00146         getValue<ParameterList>(entry_i) );
00147     }
00148     else {
00149       const ParameterEntry
00150         *thisEntryPtr = this->getEntryPtr(name_i);
00151       // If the entry does not already exist, then set it.  Otherwise, leave the
00152       // existing intery allow
00153       if(!thisEntryPtr)
00154         this->setEntry(name_i,entry_i);
00155     }
00156   }
00157   this->updateSubListNames();
00158   return *this;
00159 }
00160 
00161 
00162 ParameterList& ParameterList::disableRecursiveValidation()
00163 {
00164   disableRecursiveValidation_ = true;
00165   return *this;
00166 }
00167 
00168 
00169 void ParameterList::unused(std::ostream& os) const
00170 {
00171   for (ConstIterator i = this->begin(); i != this->end(); ++i) {
00172     if (!(entry(i).isUsed())) {
00173       os << "WARNING: Parameter \"" << name(i) << "\" " << entry(i)
00174          << " is unused" << std::endl;
00175     }
00176   }
00177 }
00178 
00179 
00180 std::string ParameterList::currentParametersString() const
00181 {
00182   std::ostringstream oss;
00183   oss << "  {\n";
00184   ParameterList::ConstIterator itr;
00185   int i;
00186   for( itr = this->begin(), i = 0; itr != this->end(); ++itr, ++i ) {
00187     const std::string &entryName = this->name(itr);
00188     const ParameterEntry &theEntry = this->entry(itr);
00189     oss
00190       << "    \""<<entryName<<"\" : "<<theEntry.getAny().typeName()
00191       <<" = "<<filterValueToString(theEntry) << "\n";
00192   }
00193   oss << "  }\n";
00194   return oss.str();
00195 }
00196 
00197 
00198 bool ParameterList::isSublist(const std::string& name_in) const
00199 {
00200   typedef StringIndexedOrderedValueObjectContainerBase SIOVOCB;
00201   const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
00202   if (param_idx != SIOVOCB::getInvalidOrdinal()) {
00203     return params_.getObjPtr(param_idx)->isList();
00204   }
00205   return false;
00206 }
00207 
00208 
00209 bool ParameterList::isParameter(const std::string& name_in) const
00210 {
00211   typedef StringIndexedOrderedValueObjectContainerBase SIOVOCB;
00212   const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
00213   if (param_idx != SIOVOCB::getInvalidOrdinal()) {
00214     return true;
00215   }
00216   return false;
00217 }
00218 
00219 
00220 bool ParameterList::remove(
00221   std::string const& name_in, bool throwIfNotExists
00222   )
00223 {
00224   typedef StringIndexedOrderedValueObjectContainerBase SIOVOCB;
00225   const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
00226   if (param_idx != SIOVOCB::getInvalidOrdinal()) {
00227     // Parameter exists
00228     params_.removeObj(param_idx);
00229     return true;
00230   }
00231   // Parameter does not exist
00232   if (throwIfNotExists) {
00233     validateEntryExists("get", name_in, 0); // Will throw
00234   }
00235   return false; // Param does not exist but that is okay
00236 }
00237 
00238 
00239 ParameterList& ParameterList::sublist(
00240   const std::string& name_in, bool mustAlreadyExist,
00241   const std::string& docString
00242   )
00243 {
00244   typedef StringIndexedOrderedValueObjectContainerBase SIOVOCB;
00245 
00246   const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
00247 
00248   Ptr<ParameterEntry> sublist_entry_ptr;
00249 
00250   if (param_idx != SIOVOCB::getInvalidOrdinal()) {
00251     // Sublist parameter exists
00252     sublist_entry_ptr = params_.getNonconstObjPtr(param_idx);
00253     validateEntryIsList(name_in, *sublist_entry_ptr);
00254   }
00255   else {
00256     // Sublist does not exist so we need to create a new one
00257     validateMissingSublistMustExist(this->name(), name_in, mustAlreadyExist);
00258     const Ordinal new_param_idx =
00259       params_.setObj(
00260         name_in,
00261         ParameterEntry(
00262           ParameterList(this->name()+std::string("->")+name_in),
00263           false,
00264           true,
00265           docString
00266           )
00267         );
00268     sublist_entry_ptr = params_.getNonconstObjPtr(new_param_idx);
00269   }
00270   
00271   return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
00272 }
00273 
00274 
00275 const ParameterList& ParameterList::sublist(const std::string& name_in) const
00276 {
00277   typedef StringIndexedOrderedValueObjectContainerBase SIOVOCB;
00278 
00279   const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
00280   if (param_idx == SIOVOCB::getInvalidOrdinal()) {
00281     validateMissingSublistMustExist(this->name(), name_in, true);
00282   }
00283 
00284   Ptr<const ParameterEntry>  sublist_entry_ptr = params_.getObjPtr(param_idx);
00285   validateEntryIsList(name_in, *sublist_entry_ptr);
00286   
00287   return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
00288 }
00289 
00290   
00291 void ParameterList::print() const
00292 {
00293   this->print(*Teuchos::VerboseObjectBase::getDefaultOStream());
00294 }
00295 
00296   
00297 std::ostream& ParameterList::print(std::ostream& os, const PrintOptions &printOptions ) const
00298 {
00299   const int   indent    = printOptions.indent();
00300   const bool  showTypes = printOptions.showTypes();
00301   const bool  showFlags = printOptions.showFlags();
00302   const bool  showDoc   = printOptions.showDoc();
00303   const std::string linePrefix(indent,' ');
00304   RCP<FancyOStream>
00305     out = getFancyOStream(rcp(&os,false));
00306   OSTab tab(out,indent);
00307   if (this->begin() == this->end()) {
00308     *out <<"[empty list]" << std::endl;
00309   }
00310   else { 
00311     // Print parameters first
00312     for (ConstIterator i = this->begin(); i != this->end(); ++i) 
00313     {
00314       const std::string &name_i = this->name(i);
00315       const ParameterEntry &entry_i = entry(i);
00316       RCP<const ParameterEntryValidator>
00317         validator = entry_i.validator();
00318       if(entry_i.isList())
00319         continue;
00320       *out << name_i;
00321       const std::string &docString = entry_i.docString();
00322       if(showTypes)
00323         *out << " : " << entry_i.getAny(false).typeName();
00324       *out << " = "; entry_i.leftshift(os,showFlags); *out << std::endl;
00325       if (showDoc) {
00326         if (nonnull(validator)) {
00327           validator->printDoc(docString,OSTab(os).o());
00328         }
00329         else if (docString.length()) {
00330           StrUtils::printLines(OSTab(out).o(),"# ",docString);
00331         }
00332       }
00333     }
00334     // Print sublists second
00335     for (ConstIterator i = this->begin(); i != this->end(); ++i) 
00336     {
00337       const ParameterEntry &entry_i = entry(i);
00338       if(!entry_i.isList())
00339         continue;
00340       const std::string &docString = entry_i.docString();
00341       const std::string &name_i = this->name(i);
00342       *out << name_i << " -> " << std::endl;
00343       if( docString.length() && showDoc ) {
00344         StrUtils::printLines(OSTab(out).o(),"# ",docString);
00345       }
00346       getValue<ParameterList>(entry_i).print(OSTab(out).o(), printOptions.copy().indent(0));
00347     }
00348   }
00349   return os;
00350 }
00351 
00352   
00353 std::ostream& ParameterList::print(std::ostream& os, int indent, bool showTypes, bool showFlags) const
00354 {
00355   return this->print(os,PrintOptions().indent(indent).showTypes(showTypes).showFlags(showFlags));
00356 }
00357 
00358 
00359 void ParameterList::validateParameters(
00360   ParameterList const& validParamList,
00361   int const depth,
00362   EValidateUsed const validateUsed,
00363   EValidateDefaults const validateDefaults
00364   ) const
00365 {
00366   typedef std::deque<ListPlusValidList> sublist_list_t;
00367 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00368   RCP<FancyOStream> out = VerboseObjectBase::getDefaultOStream();
00369   OSTab tab(out);
00370   *out << "\n*** Entering ParameterList::validateParameters(...) for "
00371     "this->name()=\""<<this->name()<<"\"...\n";
00372 #endif
00373   //
00374   // First loop through and validate the parameters at this level.
00375   //
00376   // Here we generate a list of sublists that we will search next
00377   //
00378   sublist_list_t sublist_list;
00379   ConstIterator itr;
00380   for (itr = this->begin(); itr != this->end(); ++itr) {
00381     const std::string    &entryName   = this->name(itr);
00382     const ParameterEntry &theEntry       = this->entry(itr);
00383 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00384     OSTab tab(out);
00385     *out << "\nentryName=\""<<entryName<<"\"\n";
00386 #endif
00387     if(
00388       ( theEntry.isUsed() && validateUsed!=VALIDATE_USED_ENABLED )
00389       ||
00390       ( theEntry.isDefault() && validateDefaults!=VALIDATE_DEFAULTS_ENABLED )
00391       )
00392     {
00393       continue;
00394     }
00395     const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
00396     TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00397       !validEntry, Exceptions::InvalidParameterName
00398       ,"Error, the parameter {name=\""<<entryName<<"\","
00399       "type=\""<<theEntry.getAny(false).typeName()<<"\""
00400       ",value=\""<<filterValueToString(theEntry)<<"\"}"
00401       "\nin the parameter (sub)list \""<<this->name()<<"\""
00402       "\nwas not found in the list of valid parameters!"
00403       "\n\nThe valid parameters and types are:\n"
00404       <<validParamList.currentParametersString()
00405       );
00406     RCP<const ParameterEntryValidator> validator;
00407     if (nonnull(validator=validEntry->validator())) {
00408       validator->validate(theEntry, entryName, this->name()); 
00409     }
00410     else {
00411       const bool validType =
00412         ( validEntry!=NULL
00413           ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
00414           : false
00415           );
00416       TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00417         !validType, Exceptions::InvalidParameterType
00418         ,"Error, the parameter {name=\""<<entryName<<"\","
00419         "type=\""<<theEntry.getAny(false).typeName()<<"\""
00420         ",value=\""<<filterValueToString(theEntry)<<"\"}"
00421         "\nin the parameter (sub)list \""<<this->name()<<"\""
00422         "\nexists in the list of valid parameters but has the wrong type."
00423         "\n\nThe correct type is \""
00424         << validEntry->getAny(false).typeName() << "\"."
00425         );
00426     }
00427     if( theEntry.isList() && depth > 0 ) {
00428       sublist_list.push_back(
00429         ListPlusValidList(
00430           &getValue<ParameterList>(theEntry),&getValue<ParameterList>(*validEntry)
00431           )
00432         );
00433     }
00434   }
00435   //
00436   // Now loop through the sublists and validate their parameters
00437   //
00438   for(
00439     sublist_list_t::const_iterator sl_itr = sublist_list.begin();
00440     sl_itr != sublist_list.end();
00441     ++sl_itr
00442     )
00443   {
00444     if (!sl_itr->validList->disableRecursiveValidation_) {
00445       sl_itr->list->validateParameters(
00446         *sl_itr->validList
00447         ,depth-1
00448         ,validateUsed
00449         ,validateDefaults
00450         );
00451     }
00452   }
00453 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00454   *out << "\n*** Existing ParameterList::validateParameters(...) for "
00455     "this->name()=\""<<this->name()<<"\"...\n";
00456 #endif
00457 }
00458 
00459 
00460 void ParameterList::validateParametersAndSetDefaults(
00461   ParameterList const& validParamList,
00462   int const depth
00463   )
00464 {
00465   typedef std::deque<ListPlusValidList> sublist_list_t;
00466 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00467   RCP<FancyOStream> out = VerboseObjectBase::getDefaultOStream();
00468   OSTab tab(out);
00469   *out << "\n*** Entering ParameterList::validateParametersAndSetDefaults(...) "
00470     "for this->name()=\""<<this->name()<<"\"...\n";
00471 #endif
00472   //
00473   // A) loop through and validate the parameters at this level.
00474   //
00475   // Here we generate a list of sublists that we will search next
00476   //
00477   sublist_list_t sublist_list;
00478   {
00479     Iterator itr;
00480     for (itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr) {
00481       const std::string &entryName = this->name(itr);
00482       ParameterEntry &theEntry = this->nonconstEntry(itr);
00483 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00484       OSTab tab(out);
00485       *out << "\nentryName=\""<<entryName<<"\"\n";
00486 #endif
00487       const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
00488       TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00489         !validEntry, Exceptions::InvalidParameterName
00490         ,"Error, the parameter {name=\""<<entryName<<"\","
00491         "type=\""<<theEntry.getAny(false).typeName()<<"\""
00492         ",value=\""<<filterValueToString(theEntry)<<"\"}"
00493         "\nin the parameter (sub)list \""<<this->name()<<"\""
00494         "\nwas not found in the list of valid parameters!"
00495         "\n\nThe valid parameters and types are:\n"
00496         <<validParamList.currentParametersString()
00497         );
00498       RCP<const ParameterEntryValidator> validator;
00499       if (nonnull(validator=validEntry->validator())) {
00500         validator->validateAndModify(entryName, this->name(), &theEntry);
00501         theEntry.setValidator(validator);
00502       }
00503       else {
00504         const bool validType =
00505           ( validEntry!=NULL
00506             ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
00507             : false
00508             );
00509         TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00510           !validType, Exceptions::InvalidParameterType
00511           ,"Error, the parameter {name=\""<<entryName<<"\","
00512           "type=\""<<theEntry.getAny(false).typeName()<<"\""
00513           ",value=\""<<filterValueToString(theEntry)<<"\"}"
00514           "\nin the parameter (sub)list \""<<this->name()<<"\""
00515           "\nexists in the list of valid parameters but has the wrong type."
00516           "\n\nThe correct type is \""
00517           << validEntry->getAny(false).typeName() << "\"."
00518           );
00519         // Note: If there is no validator for this item, then we can not
00520         // validate the value of the parameter, only its type!
00521       }
00522       if( theEntry.isList() && depth > 0 ) {
00523         sublist_list.push_back(
00524           ListPlusValidList(
00525             &getValue<ParameterList>(theEntry),
00526             &getValue<ParameterList>(*validEntry)
00527             )
00528           );
00529       }
00530     }
00531   }
00532   //
00533   // B) Loop through the valid parameters at this level that are not set in
00534   // *this, and set their defaults.
00535   //
00536   {
00537     ConstIterator itr;
00538     for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
00539       const std::string &validEntryName = validParamList.name(itr);
00540       const ParameterEntry &validEntry = validParamList.entry(itr);
00541       const ParameterEntry *theEntry = this->getEntryPtr(validEntryName);
00542       if (!theEntry) {
00543         // This entry does not exist, so add it.  Here we will only set the
00544         // value of the entry and its validator and and leave off the
00545         // documentation.  The reason that the validator is set is so that it
00546         // can be used to extract and validate entries in the transformed list
00547         // *this without having to refer back to the valid parameter list.
00548         ParameterEntry newEntry;
00549         newEntry.setAnyValue(
00550           validEntry.getAny(),
00551           true // isDefault
00552           );
00553         newEntry.setValidator(validEntry.validator());
00554         this->setEntry(validEntryName,newEntry);
00555       }
00556     }
00557   }
00558   //
00559   // C) Loop through the sublists and validate their parameters and set their
00560   // defaults!
00561   //
00562   for (
00563     sublist_list_t::iterator sl_itr = sublist_list.begin();
00564     sl_itr != sublist_list.end();
00565     ++sl_itr
00566     )
00567   {
00568     if (!sl_itr->validList->disableRecursiveValidation_) {
00569       sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
00570     }
00571   }
00572 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00573   *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
00574     "for this->name()=\""<<this->name()<<"\"...\n";
00575 #endif
00576 }
00577 
00578 
00579 // private
00580 
00581 
00582 void ParameterList::updateSubListNames(int depth)
00583 {
00584   const std::string this_name = this->name();
00585   Iterator itr;
00586   for( itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr ) {
00587     const std::string &entryName = this->name(itr);
00588     const ParameterEntry &theEntry = this->entry(itr);
00589     if(theEntry.isList()) {
00590       ParameterList &sublistEntry = getValue<ParameterList>(theEntry);
00591       sublistEntry.setName(this_name+std::string("->")+entryName);
00592       if(depth > 0)
00593         sublistEntry.updateSubListNames(depth-1);
00594     }
00595   }
00596 }
00597 
00598 
00599 void ParameterList::validateEntryExists(
00600   const std::string & /*funcName*/, const std::string &name_in,
00601   const ParameterEntry *entry_in
00602   ) const
00603 {
00604   TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00605     entry_in==NULL, Exceptions::InvalidParameterName
00606     ,"Error!  The parameter \""<<name_in<<"\" does not exist"\
00607     "\nin the parameter (sub)list \""<<this->name()<<"\"."
00608     "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
00609     << this->currentParametersString()
00610     );
00611 }
00612 
00613 
00614 void ParameterList::validateEntryIsList(
00615   const std::string &name_in, const ParameterEntry &entry_in
00616   ) const
00617 {
00618   TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00619     !entry_in.isList(), Exceptions::InvalidParameterType
00620     ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
00621     <<entry_in.getAny(false).typeName()<<"\"!" );
00622 }
00623 
00624 
00625 void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
00626   const std::string &sublist_name, const bool mustAlreadyExist) const
00627 {
00628   TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
00629     mustAlreadyExist, Exceptions::InvalidParameterName
00630     ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
00631     );
00632 }
00633 
00634 
00635 
00636 } // namespace Teuchos
00637 
00638 
00639 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
00640 {
00641   // Check that the top-level names of the two parameter lists are the same
00642   //const std::string &paramListName1 = list1.name();
00643   //const std::string &paramListName2 = list2.name();
00644   //if ( paramListName1 != paramListName2 ) {
00645   //  return false;
00646   //}
00647   ParameterList::ConstIterator itr1, itr2;
00648   for(
00649     itr1 = list1.begin(), itr2 = list2.begin();
00650     itr1 != list1.end() && itr2 != list2.end();
00651     ++itr1, ++itr2
00652     )
00653   {
00654     const std::string    &entryName1   = list1.name(itr1);
00655     const std::string    &entryName2   = list2.name(itr2);
00656     const ParameterEntry &entry1       = list1.entry(itr1);
00657     const ParameterEntry &entry2       = list2.entry(itr2);
00658     if( entryName1 != entryName2 ) {
00659       return false;
00660     }
00661     else if( entry1 != entry2 ) {
00662       return false;
00663     }
00664     // Note that the above statement automatically recursively compare the
00665     // sublists since ParameterList objects are stored in the 'any' variable
00666     // held by the ParameterEntry object and this same comparison operator will
00667     // be used.
00668   }
00669   // Check that the two parameter lists are the same length:
00670   if ((itr1 != list1.end()) || (itr2 != list2.end())) {
00671     return false;
00672   }
00673   return true;
00674 }
00675 
00676 
00677 bool Teuchos::haveSameValues( const ParameterList& list1, const ParameterList& list2 )
00678 {
00679   // Check that the top-level names of the two parameter lists are the same
00680   //const std::string &paramListName1 = list1.name();
00681   //const std::string &paramListName2 = list2.name();
00682   //if ( paramListName1 != paramListName2 ) {
00683   //  return false;
00684   //}
00685   ParameterList::ConstIterator itr1, itr2;
00686   for(
00687     itr1 = list1.begin(), itr2 = list2.begin();
00688     itr1 != list1.end() && itr2 != list2.end();
00689     ++itr1, ++itr2
00690     )
00691   {
00692     const std::string    &entryName1   = list1.name(itr1);
00693     const std::string    &entryName2   = list2.name(itr2);
00694     const ParameterEntry &entry1       = list1.entry(itr1);
00695     const ParameterEntry &entry2       = list2.entry(itr2);
00696     if( entryName1 != entryName2 ) {
00697       return false;
00698     }
00699     if( entry1.isList() && entry2.isList() ) {
00700       if (
00701         !haveSameValues(
00702           getValue<ParameterList>(entry1),
00703           getValue<ParameterList>(entry2))
00704         )
00705       {
00706         // Note: Above we cast to a non-const ParameterList even through we
00707         // only need a const ParameterList.  We have to do this since a
00708         // non-const ParameterList is always added initially which determines
00709         // the value.
00710         return false;
00711       }
00712     }
00713     else {
00714       if( entry1.getAny() != entry2.getAny() ) {
00715         return false;
00716       }
00717     }
00718   }
00719   // Check that the two parameter lists are the same length:
00720   if ((itr1 != list1.end()) || (itr2 != list2.end())) {
00721     return false;
00722   }
00723   return true;
00724 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines