Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_ParameterList.cpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 //#define TEUCHOS_PARAMETER_LIST_SHOW_TRACE
43 #include <deque>
44 #include <functional>
46 #include "Teuchos_FancyOStream.hpp"
47 #include "Teuchos_StrUtils.hpp"
48 #include "Teuchos_VerboseObject.hpp"
49 
50 
51 namespace {
52 
53 
54 std::string filterValueToString(const Teuchos::ParameterEntry& entry )
55 {
56  return ( entry.isList() ? std::string("...") : toString(entry.getAny()) );
57 }
58 
59 
60 struct ListPlusValidList {
62  Teuchos::ParameterList *validList;
63  ListPlusValidList(
65  ,Teuchos::ParameterList *_validList
66  )
67  :list(_list),validList(_validList)
68  {}
69 };
70 
71 
72 } // namespace
73 
74 
75 namespace Teuchos {
76 
77 
78 // Constructors/Destructor/Info
79 
80 
81 ParameterList::ParameterList(const std::string &name_in,
82  RCP<const ParameterListModifier> const& modifier_in)
83  :name_(name_in), modifier_(modifier_in)
84 {}
85 
86 
88 {
89  name_ = source.name_;
90  params_ = source.params_;
91  disableRecursiveValidation_ = source.disableRecursiveValidation_;
92  disableRecursiveModification_= source.disableRecursiveModification_;
93  disableRecursiveReconciliation_ = source.disableRecursiveReconciliation_;
94  modifier_ = source.modifier_;
95 }
96 
97 
99 {}
100 
101 
103 {
104  return params_.numObjects();
105 }
106 
107 
109 {
110  if (&source == this)
111  return *this;
112  name_ = source.name_;
113  params_ = source.params_;
114  disableRecursiveValidation_ = source.disableRecursiveValidation_;
115  disableRecursiveModification_= source.disableRecursiveModification_;
116  disableRecursiveReconciliation_ = source.disableRecursiveReconciliation_;
117  modifier_ = source.modifier_;
118  return *this;
119 }
120 
121 
122 void ParameterList::setModifier(
123  RCP<const ParameterListModifier> const& modifier_in)
124 {
125  modifier_ = modifier_in;
126 }
127 
128 
130 {
131  for( ConstIterator i = source.begin(); i != source.end(); ++i ) {
132  const std::string &name_i = this->name(i);
133  const ParameterEntry &entry_i = this->entry(i);
134  if(entry_i.isList()) {
135  this->sublist(name_i,false,entry_i.docString()).setParameters(
136  getValue<ParameterList>(entry_i) );
137  }
138  else {
139  this->setEntry(name_i,entry_i);
140  }
141  }
142  this->updateSubListNames();
143  return *this;
144 }
145 
146 
148  const ParameterList& source
149  )
150 {
151  for( ConstIterator i = source.begin(); i != source.end(); ++i ) {
152  const std::string &name_i = this->name(i);
153  const ParameterEntry &entry_i = this->entry(i);
154  if(entry_i.isList()) {
155  this->sublist(name_i,false,entry_i.docString()).setParametersNotAlreadySet(
156  getValue<ParameterList>(entry_i) );
157  }
158  else {
159  const ParameterEntry
160  *thisEntryPtr = this->getEntryPtr(name_i);
161  // If the entry does not already exist, then set it. Otherwise, leave the
162  // existing intery allow
163  if(!thisEntryPtr)
164  this->setEntry(name_i,entry_i);
165  }
166  }
167  this->updateSubListNames();
168  return *this;
169 }
170 
171 
173 {
174  disableRecursiveValidation_ = true;
175  return *this;
176 }
177 
178 
180 {
181  disableRecursiveModification_ = true;
182  return *this;
183 }
184 
185 
187 {
188  disableRecursiveReconciliation_ = true;
189  return *this;
190 }
191 
192 
194 {
198  return *this;
199 }
200 
201 
202 void ParameterList::unused(std::ostream& os) const
203 {
204  for (ConstIterator i = this->begin(); i != this->end(); ++i) {
205  if (!(entry(i).isUsed())) {
206  os << "WARNING: Parameter \"" << name(i) << "\" " << entry(i)
207  << " is unused" << std::endl;
208  }
209  }
210 }
211 
212 
214 {
215  std::ostringstream oss;
216  oss << " {\n";
218  int i;
219  for( itr = this->begin(), i = 0; itr != this->end(); ++itr, ++i ) {
220  const std::string &entryName = this->name(itr);
221  const ParameterEntry &theEntry = this->entry(itr);
222  oss
223  << " \""<<entryName<<"\" : "<<theEntry.getAny().typeName()
224  <<" = "<<filterValueToString(theEntry) << "\n";
225  }
226  oss << " }\n";
227  return oss.str();
228 }
229 
230 
231 bool ParameterList::isSublist(const std::string& name_in) const
232 {
234  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
235  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
236  return params_.getObjPtr(param_idx)->isList();
237  }
238  return false;
239 }
240 
241 
242 bool ParameterList::isParameter(const std::string& name_in) const
243 {
245  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
246  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
247  return true;
248  }
249  return false;
250 }
251 
252 
254  std::string const& name_in, bool throwIfNotExists
255  )
256 {
258  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
259  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
260  // Parameter exists
261  params_.removeObj(param_idx);
262  return true;
263  }
264  // Parameter does not exist
265  if (throwIfNotExists) {
266  validateEntryExists("get", name_in, 0); // Will throw
267  }
268  return false; // Param does not exist but that is okay
269 }
270 
271 
273  const std::string& name_in, bool mustAlreadyExist,
274  const std::string& docString
275  )
276 {
278 
279  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
280 
281  Ptr<ParameterEntry> sublist_entry_ptr;
282 
283  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
284  // Sublist parameter exists
285  sublist_entry_ptr = params_.getNonconstObjPtr(param_idx);
286  validateEntryIsList(name_in, *sublist_entry_ptr);
287  }
288  else {
289  // Sublist does not exist so we need to create a new one
290  validateMissingSublistMustExist(this->name(), name_in, mustAlreadyExist);
291  const Ordinal new_param_idx =
292  params_.setObj(
293  name_in,
295  ParameterList(this->name()+std::string("->")+name_in),
296  false,
297  true,
298  docString
299  )
300  );
301  sublist_entry_ptr = params_.getNonconstObjPtr(new_param_idx);
302  }
303 
304  return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
305 }
306 
307 
309  const std::string& name_in, RCP<const ParameterListModifier> const& modifier_in,
310  const std::string& docString
311  )
312 {
313  bool alreadyExists = this->isParameter(name_in);
315  alreadyExists, Exceptions::InvalidParameterName
316  ,"The parameter "<<this->name()<<"->\""<<name_in<<"\" already exists."
317  );
318  ParameterList &subpl = this->sublist(name_in, false, docString);
319  subpl.setModifier(modifier_in);
320  return subpl;
321 }
322 
323 
324 const ParameterList& ParameterList::sublist(const std::string& name_in) const
325 {
327 
328  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
329  if (param_idx == SIOVOCB::getInvalidOrdinal()) {
330  validateMissingSublistMustExist(this->name(), name_in, true);
331  }
332 
333  Ptr<const ParameterEntry> sublist_entry_ptr = params_.getObjPtr(param_idx);
334  validateEntryIsList(name_in, *sublist_entry_ptr);
335 
336  return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
337 }
338 
339 
341 {
343 }
344 
345 
346 std::ostream& ParameterList::print(std::ostream& os, const PrintOptions &printOptions ) const
347 {
348  const int indent = printOptions.indent();
349  const bool showTypes = printOptions.showTypes();
350  const bool showFlags = printOptions.showFlags();
351  const bool showDoc = printOptions.showDoc();
352  const std::string linePrefix(indent,' ');
354  out = getFancyOStream(rcp(&os,false));
355  OSTab tab(out,indent);
356  if (this->begin() == this->end()) {
357  *out <<"[empty list]" << std::endl;
358  }
359  else {
360  // Print parameters first
361  for (ConstIterator i = this->begin(); i != this->end(); ++i)
362  {
363  const std::string &name_i = this->name(i);
364  const ParameterEntry &entry_i = entry(i);
366  validator = entry_i.validator();
367  if(entry_i.isList())
368  continue;
369  *out << name_i;
370  const std::string &docString = entry_i.docString();
371  if(showTypes)
372  *out << " : " << entry_i.getAny(false).typeName();
373  *out << " = "; entry_i.leftshift(os,showFlags); *out << std::endl;
374  if (showDoc) {
375  if (nonnull(validator)) {
376  validator->printDoc(docString,OSTab(os).o());
377  }
378  else if (docString.length()) {
379  StrUtils::printLines(OSTab(out).o(),"# ",docString);
380  }
381  }
382  }
383  // Print sublists second
384  for (ConstIterator i = this->begin(); i != this->end(); ++i)
385  {
386  const ParameterEntry &entry_i = entry(i);
387  if(!entry_i.isList())
388  continue;
389  const std::string &docString = entry_i.docString();
390  const std::string &name_i = this->name(i);
391  *out << name_i << " -> " << std::endl;
392  if( docString.length() && showDoc ) {
393  StrUtils::printLines(OSTab(out).o(),"# ",docString);
394  }
395  getValue<ParameterList>(entry_i).print(OSTab(out).o(), printOptions.copy().indent(0));
396  }
397  }
398  return os;
399 }
400 
401 
402 std::ostream& ParameterList::print(std::ostream& os, int indent, bool showTypes, bool showFlags) const
403 {
404  return this->print(os,PrintOptions().indent(indent).showTypes(showTypes).showFlags(showFlags));
405 }
406 
407 
409  ParameterList const& validParamList,
410  int const depth,
411  EValidateUsed const validateUsed,
412  EValidateDefaults const validateDefaults
413  ) const
414 {
415  typedef std::deque<ListPlusValidList> sublist_list_t;
416 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
418  OSTab tab(out);
419  *out << "\n*** Entering ParameterList::validateParameters(...) for "
420  "this->name()=\""<<this->name()<<"\"...\n";
421 #endif
422  //
423  // First loop through and validate the parameters at this level.
424  //
425  // Here we generate a list of sublists that we will search next
426  //
427  sublist_list_t sublist_list;
428  ConstIterator itr;
429  for (itr = this->begin(); itr != this->end(); ++itr) {
430  const std::string &entryName = this->name(itr);
431  const ParameterEntry &theEntry = this->entry(itr);
432 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
433  OSTab tab(out);
434  *out << "\nentryName=\""<<entryName<<"\"\n";
435 #endif
436  if(
437  ( theEntry.isUsed() && validateUsed!=VALIDATE_USED_ENABLED )
438  ||
439  ( theEntry.isDefault() && validateDefaults!=VALIDATE_DEFAULTS_ENABLED )
440  )
441  {
442  continue;
443  }
444  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
447  ,"Error, the parameter {name=\""<<entryName<<"\","
448  "type=\""<<theEntry.getAny(false).typeName()<<"\""
449  ",value=\""<<filterValueToString(theEntry)<<"\"}"
450  "\nin the parameter (sub)list \""<<this->name()<<"\""
451  "\nwas not found in the list of valid parameters!"
452  "\n\nThe valid parameters and types are:\n"
453  <<validParamList.currentParametersString()
454  );
456  if (nonnull(validator=validEntry->validator())) {
457  validator->validate(theEntry, entryName, this->name());
458  }
459  else {
460  const bool validType =
461  ( validEntry!=NULL
462  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
463  : false
464  );
467  ,"Error, the parameter {name=\""<<entryName<<"\","
468  "type=\""<<theEntry.getAny(false).typeName()<<"\""
469  ",value=\""<<filterValueToString(theEntry)<<"\"}"
470  "\nin the parameter (sub)list \""<<this->name()<<"\""
471  "\nexists in the list of valid parameters but has the wrong type."
472  "\n\nThe correct type is \""
473  << validEntry->getAny(false).typeName() << "\"."
474  );
475  }
476  if( theEntry.isList() && depth > 0 ) {
477  sublist_list.push_back(
478  ListPlusValidList(
479  &getValue<ParameterList>(theEntry),&getValue<ParameterList>(*validEntry)
480  )
481  );
482  }
483  }
484  //
485  // Now loop through the sublists and validate their parameters
486  //
487  for(
488  sublist_list_t::const_iterator sl_itr = sublist_list.begin();
489  sl_itr != sublist_list.end();
490  ++sl_itr
491  )
492  {
493  if (!sl_itr->validList->disableRecursiveValidation_) {
494  sl_itr->list->validateParameters(
495  *sl_itr->validList
496  ,depth-1
497  ,validateUsed
498  ,validateDefaults
499  );
500  }
501  }
502 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
503  *out << "\n*** Existing ParameterList::validateParameters(...) for "
504  "this->name()=\""<<this->name()<<"\"...\n";
505 #endif
506 }
507 
508 
510  int const depth)
511 {
513  if (nonnull(modifier = valid_pl.getModifier())) {
514  modifier->modify(*this, valid_pl);
515  }
516  ConstIterator itr;
517  for (itr = valid_pl.begin(); itr != valid_pl.end(); ++itr){
518  const std::string &entry_name = itr->first;
519  const ParameterEntry &cur_entry = itr->second;
520  if (cur_entry.isList() && depth > 0){
521  ParameterList &valid_pl_sublist = valid_pl.sublist(entry_name, true);
522  if(!valid_pl_sublist.disableRecursiveModification_){
523  const ParameterEntry *validEntry = this->getEntryPtr(entry_name);
526  ,"Error, the parameter {name=\""<<entry_name<<"\","
527  "type=\""<<cur_entry.getAny(false).typeName()<<"\""
528  ",value=\""<<filterValueToString(cur_entry)<<"\"}"
529  "\nin the parameter (sub)list \""<<this->name()<<"\""
530  "\nwas not found in the list of parameters during modification."
531  "\n\nThe parameters and types are:\n"
532  <<this->currentParametersString()
533  );
534  ParameterList &pl_sublist = this->sublist(entry_name, true);
535  pl_sublist.modifyParameterList(valid_pl_sublist, depth-1);
536  }
537  }
538  }
539 }
540 
541 
543  const bool left_to_right)
544 {
545  // We do a breadth-first traversal of `valid_pl` and store references to all of the sublists
546  // in `valid_pl` in a deque with a matching deque for `this`.
547  std::deque<std::reference_wrapper<ParameterList>> refs, valid_refs, tmp, valid_tmp;
548  tmp.push_back(*this);
549  valid_tmp.push_back(valid_pl);
550  while (!valid_tmp.empty()){
551  ParameterList &cur_node = tmp.front();
552  ParameterList &valid_cur_node = valid_tmp.front();
553  tmp.pop_front();
554  valid_tmp.pop_front();
555  refs.push_back(cur_node);
556  valid_refs.push_back(valid_cur_node);
557  // Look for all sublists in valid_tmp
558  for (auto itr = valid_cur_node.begin(); itr != valid_cur_node.end(); ++itr){
559  const std::string &entry_name = itr->first;
560  if (valid_cur_node.isSublist(entry_name)){
561  const ParameterEntry &cur_entry = itr->second;
562  ParameterList &valid_cur_node_sublist = valid_cur_node.sublist(entry_name);
563  if (!valid_cur_node_sublist.disableRecursiveReconciliation_){
565  !cur_node.isSublist(entry_name), Exceptions::InvalidParameterName
566  ,"Error, the parameter {name=\"" << entry_name <<"\","
567  "type=\"" << cur_entry.getAny(false).typeName() << "\""
568  ",value=\"" << filterValueToString(cur_entry) << "\"}"
569  "\nin the parameter (sub)list \"" <<cur_node.name() << "\""
570  "\nwas not found in the list of parameters during reconciliation."
571  "\n\nThe parameters and types are:\n"
572  <<cur_node.currentParametersString()
573  );
574  if (left_to_right){
575  valid_tmp.push_back(valid_cur_node_sublist);
576  tmp.push_back(cur_node.sublist(entry_name));
577  } else{
578  valid_tmp.push_front(valid_cur_node_sublist);
579  tmp.push_front(cur_node.sublist(entry_name));
580  }
581  }
582  }
583  }
584  }
585  // We now apply the reconciliation from the bottom to the top of the parameter lists by
586  // traversing the deques from the back to the front.
588  std::deque<std::reference_wrapper<ParameterList>>::reverse_iterator ref, valid_ref;
589  for(ref = refs.rbegin(), valid_ref = valid_refs.rbegin();
590  ref != refs.rend() && valid_ref != valid_refs.rend();
591  ++ref, ++valid_ref){
592  if (nonnull(modifier = valid_ref->get().getModifier())) {
593  modifier->reconcile(ref->get());
594  }
595  }
596 }
597 
598 
600  ParameterList const& validParamList,
601  int const depth
602  )
603 {
604  typedef std::deque<ListPlusValidList> sublist_list_t;
605 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
607  OSTab tab(out);
608  *out << "\n*** Entering ParameterList::validateParametersAndSetDefaults(...) "
609  "for this->name()=\""<<this->name()<<"\"...\n";
610 #endif
611  //
612  // A) loop through and validate the parameters at this level.
613  //
614  // Here we generate a list of sublists that we will search next
615  //
616  sublist_list_t sublist_list;
617  {
618  Iterator itr;
619  for (itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr) {
620  const std::string &entryName = this->name(itr);
621  ParameterEntry &theEntry = this->nonconstEntry(itr);
622 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
623  OSTab tab(out);
624  *out << "\nentryName=\""<<entryName<<"\"\n";
625 #endif
626  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
629  ,"Error, the parameter {name=\""<<entryName<<"\","
630  "type=\""<<theEntry.getAny(false).typeName()<<"\""
631  ",value=\""<<filterValueToString(theEntry)<<"\"}"
632  "\nin the parameter (sub)list \""<<this->name()<<"\""
633  "\nwas not found in the list of valid parameters!"
634  "\n\nThe valid parameters and types are:\n"
635  <<validParamList.currentParametersString()
636  );
638  if (nonnull(validator=validEntry->validator())) {
639  validator->validateAndModify(entryName, this->name(), &theEntry);
640  theEntry.setValidator(validator);
641  }
642  else {
643  const bool validType =
644  ( validEntry!=NULL
645  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
646  : false
647  );
650  ,"Error, the parameter {name=\""<<entryName<<"\","
651  "type=\""<<theEntry.getAny(false).typeName()<<"\""
652  ",value=\""<<filterValueToString(theEntry)<<"\"}"
653  "\nin the parameter (sub)list \""<<this->name()<<"\""
654  "\nexists in the list of valid parameters but has the wrong type."
655  "\n\nThe correct type is \""
656  << validEntry->getAny(false).typeName() << "\"."
657  );
658  // Note: If there is no validator for this item, then we can not
659  // validate the value of the parameter, only its type!
660  }
661  if( theEntry.isList() && depth > 0 ) {
662  sublist_list.push_back(
663  ListPlusValidList(
664  &getValue<ParameterList>(theEntry),
665  &getValue<ParameterList>(*validEntry)
666  )
667  );
668  }
669  }
670  }
671  //
672  // B) Loop through the valid parameters at this level that are not set in
673  // *this, and set their defaults.
674  //
675  {
676  ConstIterator itr;
677  for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
678  const std::string &validEntryName = validParamList.name(itr);
679  const ParameterEntry &validEntry = validParamList.entry(itr);
680  const ParameterEntry *theEntry = this->getEntryPtr(validEntryName);
681  if (!theEntry) {
682  // This entry does not exist, so add it. Here we will only set the
683  // value of the entry and its validator and and leave off the
684  // documentation. The reason that the validator is set is so that it
685  // can be used to extract and validate entries in the transformed list
686  // *this without having to refer back to the valid parameter list.
687  ParameterEntry newEntry;
688  newEntry.setAnyValue(
689  validEntry.getAny(),
690  true // isDefault
691  );
692  newEntry.setValidator(validEntry.validator());
693  this->setEntry(validEntryName,newEntry);
694  }
695  }
696  }
697  //
698  // C) Loop through the sublists and validate their parameters and set their
699  // defaults!
700  //
701  for (
702  sublist_list_t::iterator sl_itr = sublist_list.begin();
703  sl_itr != sublist_list.end();
704  ++sl_itr
705  )
706  {
707  if (!sl_itr->validList->disableRecursiveValidation_) {
708  sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
709  }
710  }
711 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
712  *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
713  "for this->name()=\""<<this->name()<<"\"...\n";
714 #endif
715 }
716 
717 
718 // private
719 
720 
721 void ParameterList::updateSubListNames(int depth)
722 {
723  const std::string this_name = this->name();
724  Iterator itr;
725  for( itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr ) {
726  const std::string &entryName = this->name(itr);
727  const ParameterEntry &theEntry = this->entry(itr);
728  if(theEntry.isList()) {
729  ParameterList &sublistEntry = getValue<ParameterList>(theEntry);
730  sublistEntry.setName(this_name+std::string("->")+entryName);
731  if(depth > 0)
732  sublistEntry.updateSubListNames(depth-1);
733  }
734  }
735 }
736 
737 
738 void ParameterList::validateEntryExists(
739  const std::string & /*funcName*/, const std::string &name_in,
740  const ParameterEntry *entry_in
741  ) const
742 {
744  entry_in==NULL, Exceptions::InvalidParameterName
745  ,"Error! The parameter \""<<name_in<<"\" does not exist"\
746  "\nin the parameter (sub)list \""<<this->name()<<"\"."
747  "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
748  << this->currentParametersString()
749  );
750 }
751 
752 
753 void ParameterList::validateEntryIsList(
754  const std::string &name_in, const ParameterEntry &entry_in
755  ) const
756 {
758  !entry_in.isList(), Exceptions::InvalidParameterType
759  ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
760  <<entry_in.getAny(false).typeName()<<"\"!" );
761 }
762 
763 
764 void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
765  const std::string &sublist_name, const bool mustAlreadyExist) const
766 {
768  mustAlreadyExist, Exceptions::InvalidParameterName
769  ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
770  );
771 }
772 
773 
774 } // namespace Teuchos
775 
776 
777 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
778 {
779  // Check that the top-level names of the two parameter lists are the same
780  //const std::string &paramListName1 = list1.name();
781  //const std::string &paramListName2 = list2.name();
782  //if ( paramListName1 != paramListName2 ) {
783  // return false;
784  //}
785  if (!Teuchos::haveSameModifiers(list1, list2)){
786  return false;
787  }
788  ParameterList::ConstIterator itr1, itr2;
789  for(
790  itr1 = list1.begin(), itr2 = list2.begin();
791  itr1 != list1.end() && itr2 != list2.end();
792  ++itr1, ++itr2
793  )
794  {
795  const std::string &entryName1 = list1.name(itr1);
796  const std::string &entryName2 = list2.name(itr2);
797  const ParameterEntry &entry1 = list1.entry(itr1);
798  const ParameterEntry &entry2 = list2.entry(itr2);
799  if( entryName1 != entryName2 ) {
800  return false;
801  }
802  else if( entry1 != entry2 ) {
803  return false;
804  }
805  // Note that the above statement automatically recursively compare the
806  // sublists since ParameterList objects are stored in the 'any' variable
807  // held by the ParameterEntry object and this same comparison operator will
808  // be used.
809  }
810  // Check that the two parameter lists are the same length:
811  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
812  return false;
813  }
814  return true;
815 }
816 
817 
818 bool Teuchos::haveSameModifiers(const ParameterList &list1, const ParameterList &list2) {
819  // Check that the modifiers are the same
820  ParameterList::ConstIterator itr1, itr2;
821  for(
822  itr1 = list1.begin(), itr2 = list2.begin();
823  itr1 != list1.end() && itr2 != list2.end();
824  ++itr1, ++itr2
825  )
826  {
827  const Teuchos::RCP<const ParameterListModifier> &modifier1 = list1.getModifier();
828  const Teuchos::RCP<const ParameterListModifier> &modifier2 = list2.getModifier();
829  if( modifier1 != modifier2 ) {
830  return false;
831  }
832  const Teuchos::ParameterEntry &entry1 = itr1->second;
833  const Teuchos::ParameterEntry &entry2 = itr2->second;
834  if (entry1.isList() && entry2.isList()){
835  if ( !haveSameModifiers( Teuchos::getValue<ParameterList>(entry1),
836  Teuchos::getValue<ParameterList>(entry2) ) ){
837  return false;
838  }
839  }
840  }
841  return true;
842 }
843 
844 
845 bool Teuchos::haveSameValues( const ParameterList& list1, const ParameterList& list2, bool verbose )
846 {
847  // Check that the top-level names of the two parameter lists are the same
848  //const std::string &paramListName1 = list1.name();
849  //const std::string &paramListName2 = list2.name();
850  //if ( paramListName1 != paramListName2 ) {
851  // return false;
852  //}
853  ParameterList::ConstIterator itr1, itr2;
854  for(
855  itr1 = list1.begin(), itr2 = list2.begin();
856  itr1 != list1.end() && itr2 != list2.end();
857  ++itr1, ++itr2
858  )
859  {
860  const std::string &entryName1 = list1.name(itr1);
861  const std::string &entryName2 = list2.name(itr2);
862  const ParameterEntry &entry1 = list1.entry(itr1);
863  const ParameterEntry &entry2 = list2.entry(itr2);
864  if( entryName1 != entryName2 ) {
865  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
866  return false;
867  }
868  if( entry1.isList() && entry2.isList() ) {
869  if (
871  getValue<ParameterList>(entry1),
872  getValue<ParameterList>(entry2),
873  verbose)
874  )
875  {
876  // Note: Above we cast to a non-const ParameterList even through we
877  // only need a const ParameterList. We have to do this since a
878  // non-const ParameterList is always added initially which determines
879  // the value.
880  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
881  return false;
882  }
883  }
884  else {
885  if( entry1.getAny() != entry2.getAny() ) {
886  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
887  return false;
888  }
889  }
890  }
891  // Check that the two parameter lists are the same length:
892  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
893  if (verbose) std::cerr << "lists are not the same size\n";
894  return false;
895  }
896  return true;
897 }
898 
899 
900 bool Teuchos::haveSameValuesSorted( const ParameterList& list1, const ParameterList& list2, bool verbose )
901 {
902  // Check that the top-level names of the two parameter lists are the same
903  //const std::string &paramListName1 = list1.name();
904  //const std::string &paramListName2 = list2.name();
905  //if ( paramListName1 != paramListName2 ) {
906  // return false;
907  //}
908  ParameterList::ConstIterator itr1, itr2;
909  Array<std::string> arr1, arr2;
910  for(itr1 = list1.begin(); itr1 != list1.end(); ++itr1){
911  arr1.push_back(list1.name(itr1));
912  }
913  for(itr2 = list2.begin(); itr2 != list2.end(); ++itr2){
914  arr2.push_back(list2.name(itr2));
915  }
916  // Check that the two parameter lists are the same length:
917  if (arr1.size() != arr2.size()) {
918  if (verbose) std::cerr << "lists are not the same size\n";
919  return false;
920  }
921  std::sort(arr1.begin(), arr1.end());
922  std::sort(arr2.begin(), arr2.end());
923  Array<std::string>::iterator iarr1, iarr2;
924  for(
925  iarr1 = arr1.begin(), iarr2 = arr2.begin();
926  iarr1 != arr1.end() && iarr2 != arr2.end();
927  ++iarr1, ++iarr2
928  )
929  {
930  const std::string &entryName1 = *iarr1;
931  const std::string &entryName2 = *iarr2;
932  const ParameterEntry &entry1 = list1.getEntry(entryName1);
933  const ParameterEntry &entry2 = list2.getEntry(entryName2);
934  if( entryName1 != entryName2 ) {
935  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
936  return false;
937  }
938  if( entry1.isList() && entry2.isList() ) {
939  if (
941  getValue<ParameterList>(entry1),
942  getValue<ParameterList>(entry2),
943  verbose)
944  )
945  {
946  // Note: Above we cast to a non-const ParameterList even through we
947  // only need a const ParameterList. We have to do this since a
948  // non-const ParameterList is always added initially which determines
949  // the value.
950  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
951  return false;
952  }
953  }
954  else {
955  if( entry1.getAny() != entry2.getAny() ) {
956  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
957  return false;
958  }
959  }
960  }
961  return true;
962 }
Teuchos::ParameterEntry::isUsed
bool isUsed() const
Return whether or not the value has been used; i.e., whether or not the value has been retrieved via ...
Definition: Teuchos_ParameterEntry.hpp:384
Teuchos::ParameterList::EValidateDefaults
EValidateDefaults
Validation defaults enum.
Definition: Teuchos_ParameterList.hpp:81
Teuchos::ParameterList::EValidateUsed
EValidateUsed
Validation used enum.
Definition: Teuchos_ParameterList.hpp:69
Teuchos_ParameterList.hpp
Templated Parameter List class.
Teuchos::StringIndexedOrderedValueObjectContainer::getNonconstObjPtr
Ptr< ObjType > getNonconstObjPtr(const Ordinal &idx)
Get a nonconst semi-persisting association with the stored object indexed by ordinal.
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:353
Teuchos::ParameterList::numParams
Ordinal numParams() const
Get the number of stored parameters.
Definition: Teuchos_ParameterList.cpp:102
Teuchos::ParameterList::disableRecursiveModification
ParameterList & disableRecursiveModification()
Definition: Teuchos_ParameterList.cpp:179
Teuchos::VerboseObjectBase::getDefaultOStream
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
Definition: Teuchos_VerboseObject.cpp:77
Teuchos::FilteredIterator
C++ Standard Library compatable filtered iterator.
Definition: Teuchos_FilteredIterator.hpp:60
Teuchos::ParameterList::setName
ParameterList & setName(const std::string &name)
Set the name of *this list.
Definition: Teuchos_ParameterList.hpp:939
Teuchos_StrUtils.hpp
A std::string utilities class for Teuchos.
Teuchos::ParameterList::getEntryPtr
ParameterEntry * getEntryPtr(const std::string &name)
Retrieves the pointer for an entry with the name name if it exists.
Definition: Teuchos_ParameterList.hpp:1143
TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG
#define TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Definition: Teuchos_TestForException.hpp:246
Teuchos::ParameterEntry::validator
RCP< const ParameterEntryValidator > validator() const
Return the (optional) validator object.
Definition: Teuchos_ParameterEntry.hpp:402
Teuchos::ParameterList::end
ConstIterator end() const
An iterator pointing beyond the last entry.
Definition: Teuchos_ParameterList.hpp:1236
Teuchos::ParameterEntry::isList
bool isList() const
Return whether or not the value itself is a list.
Definition: Teuchos_ParameterEntry.cpp:115
Teuchos::ParameterList::operator=
ParameterList & operator=(const ParameterList &source)
Replace the current parameter list with source.
Definition: Teuchos_ParameterList.cpp:108
Teuchos::rcp
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
Definition: Teuchos_RCPDecl.hpp:1242
Teuchos::StringIndexedOrderedValueObjectContainer::removeObj
void removeObj(const Ordinal &idx)
Remove an object given its ordinal index.
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:495
Teuchos::Exceptions::InvalidParameterType
Definition: Teuchos_ParameterListExceptions.hpp:74
Teuchos::ParameterList::remove
bool remove(std::string const &name, bool throwIfNotExists=true)
Remove a parameter (does not depend on the type of the parameter).
Definition: Teuchos_ParameterList.cpp:253
Teuchos::Array< std::string >::iterator
std::vector< std::string >::iterator iterator
The type of a forward iterator.
Definition: Teuchos_Array.hpp:264
Teuchos::StringIndexedOrderedValueObjectContainer::getObjOrdinalIndex
Ordinal getObjOrdinalIndex(const std::string &key) const
Get the ordinal index given the string key.
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:464
Teuchos::any::type
const std::type_info & type() const
Return the type of value being stored.
Definition: Teuchos_any.hpp:208
Teuchos::RCP
Smart reference counting pointer class for automatic garbage collection.
Definition: Teuchos_RCPDecl.hpp:429
Teuchos::ParameterList::disableRecursiveReconciliation
ParameterList & disableRecursiveReconciliation()
Definition: Teuchos_ParameterList.cpp:186
Teuchos::Ptr
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
Definition: Teuchos_PtrDecl.hpp:104
Teuchos::StringIndexedOrderedValueObjectContainer::numObjects
Ordinal numObjects() const
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:444
Teuchos::ParameterList::setParametersNotAlreadySet
ParameterList & setParametersNotAlreadySet(const ParameterList &source)
Definition: Teuchos_ParameterList.cpp:147
Teuchos::ParameterList::isSublist
bool isSublist(const std::string &name) const
Whether the given sublist exists in this list.
Definition: Teuchos_ParameterList.cpp:231
Teuchos::ParameterEntry::isDefault
bool isDefault() const
Indicate whether this entry takes on the default value.
Definition: Teuchos_ParameterEntry.hpp:393
Teuchos::ParameterList::validateParameters
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
Validate the parameters in this list given valid selections in the input list.
Definition: Teuchos_ParameterList.cpp:408
Teuchos::any::toString
std::string toString(const any &rhs)
Converts the value in any to a std::string.
Definition: Teuchos_any.hpp:398
Teuchos::ParameterEntry::getAny
any & getAny(bool activeQry=true)
Direct access to the Teuchos::any data value underlying this object. The bool argument activeQry (def...
Definition: Teuchos_ParameterEntry.hpp:364
Teuchos::ParameterList::isParameter
bool isParameter(const std::string &name) const
Whether the given parameter exists in this list.
Definition: Teuchos_ParameterList.cpp:242
Teuchos::ParameterList::setEntry
ParameterList & setEntry(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
Definition: Teuchos_ParameterList.hpp:1010
Teuchos::ParameterList::print
void print() const
Print function to use in debugging in a debugger.
Definition: Teuchos_ParameterList.cpp:340
Teuchos::ParameterEntry::setValidator
void setValidator(RCP< const ParameterEntryValidator > const &validator)
Set the validator.
Definition: Teuchos_ParameterEntry.cpp:89
Teuchos::StrUtils::printLines
static std::ostream & printLines(std::ostream &os, const std::string &linePrefix, const std::string &lines)
Print lines with prefix first.
Definition: Teuchos_StrUtils.cpp:412
Teuchos::ParameterList::unused
void unused(std::ostream &os) const
Print out unused parameters in the ParameterList.
Definition: Teuchos_ParameterList.cpp:202
Teuchos::ParameterList::PrintOptions
Utility class for setting and passing in print options.
Definition: Teuchos_ParameterList.hpp:150
Teuchos::ParameterList::disableRecursiveAll
ParameterList & disableRecursiveAll()
Definition: Teuchos_ParameterList.cpp:193
Teuchos::ParameterList::getModifier
RCP< const ParameterListModifier > getModifier() const
Return the optional modifier object.
Definition: Teuchos_ParameterList.hpp:1192
Teuchos::ParameterList::~ParameterList
virtual ~ParameterList()
Destructor.
Definition: Teuchos_ParameterList.cpp:98
Teuchos::ParameterList::sublist
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Creates an empty sublist and returns a reference to the sublist name. If the list already exists,...
Definition: Teuchos_ParameterList.cpp:272
Teuchos::ParameterList::haveSameValuesSorted
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT bool haveSameValuesSorted(const ParameterList &list1, const ParameterList &list2, bool verbose=false)
Returns true if two parameter lists have the same values independent of ordering.
Teuchos::ParameterList::setParameters
ParameterList & setParameters(const ParameterList &source)
Definition: Teuchos_ParameterList.cpp:129
Teuchos::any::typeName
std::string typeName() const
Return the name of the type.
Definition: Teuchos_any.hpp:214
Teuchos::ParameterList::reconcileParameterList
void reconcileParameterList(ParameterList &validParamList, const bool left_to_right=true)
Reconcile a parameter list after validation.
Definition: Teuchos_ParameterList.cpp:542
Teuchos::VALIDATE_USED_ENABLED
@ VALIDATE_USED_ENABLED
Definition: Teuchos_ParameterList.hpp:70
Teuchos::ParameterList::currentParametersString
std::string currentParametersString() const
Create a single formated std::string of all of the zero-level parameters in this list.
Definition: Teuchos_ParameterList.cpp:213
Teuchos::VALIDATE_DEFAULTS_ENABLED
@ VALIDATE_DEFAULTS_ENABLED
Definition: Teuchos_ParameterList.hpp:82
Teuchos::basic_OSTab
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object.
Definition: Teuchos_FancyOStream.hpp:654
Teuchos::RCP::get
T * get() const
Get the raw C++ pointer to the underlying object.
Definition: Teuchos_RCP.hpp:388
Teuchos::StringIndexedOrderedValueObjectContainerBase
Base types for StringIndexedOrderedValueObjectContainer.
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:59
Teuchos::ParameterList::name
const std::string & name() const
The name of this ParameterList.
Definition: Teuchos_ParameterList.hpp:1200
Teuchos::ParameterList::validateParametersAndSetDefaults
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
Validate the parameters in this list given valid selections in the input list and set defaults for th...
Definition: Teuchos_ParameterList.cpp:599
Teuchos::StringIndexedOrderedValueObjectContainer::setObj
Ordinal setObj(const std::string &key, const ObjType &obj)
Set (or reset) object by value and return its ordinal index.
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:476
Teuchos::Exceptions::InvalidParameterName
Definition: Teuchos_ParameterListExceptions.hpp:68
Teuchos::nonnull
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
Definition: Teuchos_RCPStdSharedPtrConversionsDecl.hpp:159
Teuchos::ParameterList
A list of parameters of arbitrary type.
Definition: Teuchos_ParameterList.hpp:133
Teuchos
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
Teuchos::ParameterList::modifyParameterList
void modifyParameterList(ParameterList &validParamList, int const depth=1000)
Modify the valid parameter list prior to validation.
Definition: Teuchos_ParameterList.cpp:509
Teuchos::ParameterList::disableRecursiveValidation
ParameterList & disableRecursiveValidation()
Definition: Teuchos_ParameterList.cpp:172
Teuchos::ParameterList::ParameterList
ParameterList()=default
Constructor.
Teuchos::ParameterEntry
This object is held as the "value" in the Teuchos::ParameterList std::map.
Definition: Teuchos_ParameterEntry.hpp:67
Teuchos::ParameterList::entry
const ParameterEntry & entry(ConstIterator i) const
Access to ParameterEntry (i.e., returns i->second)
Definition: Teuchos_ParameterList.hpp:1248
TEUCHOS_TEST_FOR_EXCEPTION
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Definition: Teuchos_TestForException.hpp:170
Teuchos::ParameterEntry::leftshift
std::ostream & leftshift(std::ostream &os, bool printFlags=true) const
Output a non-list parameter to the given output stream.
Definition: Teuchos_ParameterEntry.cpp:120
Teuchos::OSTab
basic_OSTab< char > OSTab
Definition: Teuchos_FancyOStream.hpp:851
Teuchos::ParameterEntry::setAnyValue
void setAnyValue(const any &value, bool isDefault=false)
Set the value as an any object.
Definition: Teuchos_ParameterEntry.cpp:77
Teuchos::StringIndexedOrderedValueObjectContainer::getObjPtr
Ptr< const ObjType > getObjPtr(const Ordinal &idx) const
Get a const semi-persisting association with the stored object indexed by ordinal.
Definition: Teuchos_StringIndexedOrderedValueObjectContainer.hpp:362
Teuchos::ParameterList::begin
ConstIterator begin() const
An iterator pointing to the first entry.
Definition: Teuchos_ParameterList.hpp:1230
Teuchos::ParameterList::haveSameModifiers
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT bool haveSameModifiers(const ParameterList &list1, const ParameterList &list2)
Returns true if two parameter lists have the same modifiers.
Teuchos::ParameterEntry::docString
std::string docString() const
Return the (optional) documentation std::string.
Definition: Teuchos_ParameterEntry.hpp:397
Teuchos::ParameterList::haveSameValues
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT bool haveSameValues(const ParameterList &list1, const ParameterList &list2, bool verbose=false)
Returns true if two parameter lists have the same values.