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