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