|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
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 ¶mListName1 = list1.name(); 00656 //const std::string ¶mListName2 = 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 ¶mListName1 = list1.name(); 00694 //const std::string ¶mListName2 = 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 }
1.7.4