|
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 // 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 ¶mListName1 = list1.name(); 00643 //const std::string ¶mListName2 = 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 ¶mListName1 = list1.name(); 00681 //const std::string ¶mListName2 = 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 }
1.7.6.1