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