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 //
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  ParameterList &pl = getValue<ParameterList>(entry_i);
136  ParameterList &this_pl = this->sublist(name_i, false, entry_i.docString());
137  this_pl.setParameters(pl);
138  this_pl.setModifier(pl.getModifier());
139  } else {
140  this->setEntry(name_i, entry_i);
141  }
142  }
143  this->updateSubListNames();
144  return *this;
145 }
146 
147 
149  const ParameterList& source
150  )
151 {
152  for (ConstIterator i = source.begin(); i != source.end(); ++i) {
153  const std::string &name_i = this->name(i);
154  const ParameterEntry &entry_i = this->entry(i);
155  if (entry_i.isList()) {
156  ParameterList pl = getValue<ParameterList>(entry_i);
157  if (this->isSublist(name_i)){
158  this->sublist(name_i, true).setParametersNotAlreadySet(pl);
159  } else{
160  this->sublist(name_i, pl.getModifier(), entry_i.docString())
162  }
163  } else {
164  const ParameterEntry *thisEntryPtr = this->getEntryPtr(name_i);
165  // If the entry does not already exist, then set it. Otherwise, leave the
166  // existing entry alone.
167  if (!thisEntryPtr)
168  this->setEntry(name_i, entry_i);
169  }
170  }
171  this->updateSubListNames();
172  return *this;
173 }
174 
175 
177 {
178  disableRecursiveValidation_ = true;
179  return *this;
180 }
181 
182 
184 {
185  disableRecursiveModification_ = true;
186  return *this;
187 }
188 
189 
191 {
192  disableRecursiveReconciliation_ = true;
193  return *this;
194 }
195 
196 
198 {
202  return *this;
203 }
204 
205 
206 void ParameterList::unused(std::ostream& os) const
207 {
208  for (ConstIterator i = this->begin(); i != this->end(); ++i) {
209  if (!(entry(i).isUsed())) {
210  os << "WARNING: Parameter \"" << name(i) << "\" " << entry(i)
211  << " is unused" << std::endl;
212  }
213  }
214 }
215 
216 
218 {
219  std::ostringstream oss;
220  oss << " {\n";
222  int i;
223  for( itr = this->begin(), i = 0; itr != this->end(); ++itr, ++i ) {
224  const std::string &entryName = this->name(itr);
225  const ParameterEntry &theEntry = this->entry(itr);
226  oss
227  << " \""<<entryName<<"\" : "<<theEntry.getAny().typeName()
228  <<" = "<<filterValueToString(theEntry) << "\n";
229  }
230  oss << " }\n";
231  return oss.str();
232 }
233 
234 
235 bool ParameterList::isSublist(const std::string& name_in) const
236 {
238  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
239  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
240  return params_.getObjPtr(param_idx)->isList();
241  }
242  return false;
243 }
244 
245 
246 bool ParameterList::isParameter(const std::string& name_in) const
247 {
249  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
250  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
251  return true;
252  }
253  return false;
254 }
255 
256 
258  std::string const& name_in, bool throwIfNotExists
259  )
260 {
262  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
263  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
264  // Parameter exists
265  params_.removeObj(param_idx);
266  return true;
267  }
268  // Parameter does not exist
269  if (throwIfNotExists) {
270  validateEntryExists("get", name_in, 0); // Will throw
271  }
272  return false; // Param does not exist but that is okay
273 }
274 
275 
277  const std::string& name_in, bool mustAlreadyExist,
278  const std::string& docString
279  )
280 {
282 
283  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
284 
285  Ptr<ParameterEntry> sublist_entry_ptr;
286 
287  if (param_idx != SIOVOCB::getInvalidOrdinal()) {
288  // Sublist parameter exists
289  sublist_entry_ptr = params_.getNonconstObjPtr(param_idx);
290  validateEntryIsList(name_in, *sublist_entry_ptr);
291  }
292  else {
293  // Sublist does not exist so we need to create a new one
294  validateMissingSublistMustExist(this->name(), name_in, mustAlreadyExist);
295  const Ordinal new_param_idx =
296  params_.setObj(
297  name_in,
299  ParameterList(this->name()+std::string("->")+name_in),
300  false,
301  true,
302  docString
303  )
304  );
305  sublist_entry_ptr = params_.getNonconstObjPtr(new_param_idx);
306  }
307 
308  return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
309 }
310 
311 
313  const std::string& name_in, RCP<const ParameterListModifier> const& modifier_in,
314  const std::string& docString
315  )
316 {
317  bool alreadyExists = this->isParameter(name_in);
319  alreadyExists, Exceptions::InvalidParameterName
320  ,"The parameter "<<this->name()<<"->\""<<name_in<<"\" already exists."
321  );
322  ParameterList &subpl = this->sublist(name_in, false, docString);
323  subpl.setModifier(modifier_in);
324  return subpl;
325 }
326 
327 
328 const ParameterList& ParameterList::sublist(const std::string& name_in) const
329 {
331 
332  const Ordinal param_idx = params_.getObjOrdinalIndex(name_in);
333  if (param_idx == SIOVOCB::getInvalidOrdinal()) {
334  validateMissingSublistMustExist(this->name(), name_in, true);
335  }
336 
337  Ptr<const ParameterEntry> sublist_entry_ptr = params_.getObjPtr(param_idx);
338  validateEntryIsList(name_in, *sublist_entry_ptr);
339 
340  return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
341 }
342 
343 
345 {
347 }
348 
349 
350 std::ostream& ParameterList::print(std::ostream& os, const PrintOptions &printOptions ) const
351 {
352  const int indent = printOptions.indent();
353  const bool showTypes = printOptions.showTypes();
354  const bool showFlags = printOptions.showFlags();
355  const bool showDoc = printOptions.showDoc();
356  const bool showDefault = printOptions.showDefault();
357  const std::string linePrefix(indent,' ');
359  out = getFancyOStream(rcp(&os,false));
360  OSTab tab(out,indent);
361  if (this->begin() == this->end()) {
362  *out <<"[empty list]" << std::endl;
363  }
364  else {
365  // Print parameters first
366  for (ConstIterator i = this->begin(); i != this->end(); ++i)
367  {
368  const std::string &name_i = this->name(i);
369  const ParameterEntry &entry_i = entry(i);
371  validator = entry_i.validator();
372  if(entry_i.isList())
373  continue;
374  if(!showDefault && entry_i.isDefault())
375  continue;
376  *out << name_i;
377  const std::string &docString = entry_i.docString();
378  if(showTypes)
379  *out << " : " << entry_i.getAny(false).typeName();
380  *out << " = "; entry_i.leftshift(os,showFlags); *out << std::endl;
381  if (showDoc) {
382  if (nonnull(validator)) {
383  validator->printDoc(docString,OSTab(os).o());
384  }
385  else if (docString.length()) {
386  StrUtils::printLines(OSTab(out).o(),"# ",docString);
387  }
388  }
389  }
390  // Print sublists second
391  for (ConstIterator i = this->begin(); i != this->end(); ++i)
392  {
393  const ParameterEntry &entry_i = entry(i);
394  if(!entry_i.isList())
395  continue;
396  const std::string &docString = entry_i.docString();
397  const std::string &name_i = this->name(i);
398  *out << name_i << " -> " << std::endl;
399  if( docString.length() && showDoc ) {
400  StrUtils::printLines(OSTab(out).o(),"# ",docString);
401  }
402  getValue<ParameterList>(entry_i).print(OSTab(out).o(), printOptions.copy().indent(0));
403  }
404  }
405  return os;
406 }
407 
408 
409 std::ostream& ParameterList::print(std::ostream& os, int indent, bool showTypes, bool showFlags, bool showDefault) const
410 {
411  return this->print(os,PrintOptions().indent(indent).showTypes(showTypes).showFlags(showFlags).showDefault(showDefault));
412 }
413 
414 
416  ParameterList const& validParamList,
417  int const depth,
418  EValidateUsed const validateUsed,
419  EValidateDefaults const validateDefaults
420  ) const
421 {
422  typedef std::deque<ListPlusValidList> sublist_list_t;
423 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
425  OSTab tab(out);
426  *out << "\n*** Entering ParameterList::validateParameters(...) for "
427  "this->name()=\""<<this->name()<<"\"...\n";
428 #endif
429  //
430  // First loop through and validate the parameters at this level.
431  //
432  // Here we generate a list of sublists that we will search next
433  //
434  sublist_list_t sublist_list;
435  ConstIterator itr;
436  for (itr = this->begin(); itr != this->end(); ++itr) {
437  const std::string &entryName = this->name(itr);
438  const ParameterEntry &theEntry = this->entry(itr);
439 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
440  OSTab tab(out);
441  *out << "\nentryName=\""<<entryName<<"\"\n";
442 #endif
443  if(
444  ( theEntry.isUsed() && validateUsed!=VALIDATE_USED_ENABLED )
445  ||
446  ( theEntry.isDefault() && validateDefaults!=VALIDATE_DEFAULTS_ENABLED )
447  )
448  {
449  continue;
450  }
451  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
454  ,"Error, the parameter {name=\""<<entryName<<"\","
455  "type=\""<<theEntry.getAny(false).typeName()<<"\""
456  ",value=\""<<filterValueToString(theEntry)<<"\"}"
457  "\nin the parameter (sub)list \""<<this->name()<<"\""
458  "\nwas not found in the list of valid parameters!"
459  "\n\nThe valid parameters and types are:\n"
460  <<validParamList.currentParametersString()
461  );
463  if (nonnull(validator=validEntry->validator())) {
464  validator->validate(theEntry, entryName, this->name());
465  }
466  else {
467  const bool validType =
468  ( validEntry!=NULL
469  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
470  : false
471  );
474  ,"Error, the parameter {name=\""<<entryName<<"\","
475  "type=\""<<theEntry.getAny(false).typeName()<<"\""
476  ",value=\""<<filterValueToString(theEntry)<<"\"}"
477  "\nin the parameter (sub)list \""<<this->name()<<"\""
478  "\nexists in the list of valid parameters but has the wrong type."
479  "\n\nThe correct type is \""
480  << validEntry->getAny(false).typeName() << "\"."
481  );
482  }
483  if( theEntry.isList() && depth > 0 ) {
484  sublist_list.push_back(
485  ListPlusValidList(
486  &getValue<ParameterList>(theEntry),&getValue<ParameterList>(*validEntry)
487  )
488  );
489  }
490  }
491  //
492  // Now loop through the sublists and validate their parameters
493  //
494  for(
495  sublist_list_t::const_iterator sl_itr = sublist_list.begin();
496  sl_itr != sublist_list.end();
497  ++sl_itr
498  )
499  {
500  if (!sl_itr->validList->disableRecursiveValidation_) {
501  sl_itr->list->validateParameters(
502  *sl_itr->validList
503  ,depth-1
504  ,validateUsed
505  ,validateDefaults
506  );
507  }
508  }
509 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
510  *out << "\n*** Existing ParameterList::validateParameters(...) for "
511  "this->name()=\""<<this->name()<<"\"...\n";
512 #endif
513 }
514 
515 
517  int const depth)
518 {
520  if (nonnull(modifier = valid_pl.getModifier())) {
521  modifier->modify(*this, valid_pl);
522  }
523  ConstIterator itr;
524  for (itr = valid_pl.begin(); itr != valid_pl.end(); ++itr){
525  const std::string &entry_name = itr->first;
526  const ParameterEntry &cur_entry = itr->second;
527  if (cur_entry.isList() && depth > 0){
528  ParameterList &valid_pl_sublist = valid_pl.sublist(entry_name, true);
529  if(!valid_pl_sublist.disableRecursiveModification_){
530  const ParameterEntry *validEntry = this->getEntryPtr(entry_name);
533  ,"Error, the parameter {name=\""<<entry_name<<"\","
534  "type=\""<<cur_entry.getAny(false).typeName()<<"\""
535  ",value=\""<<filterValueToString(cur_entry)<<"\"}"
536  "\nin the parameter (sub)list \""<<this->name()<<"\""
537  "\nwas not found in the list of parameters during modification."
538  "\n\nThe parameters and types are:\n"
539  <<this->currentParametersString()
540  );
541  ParameterList &pl_sublist = this->sublist(entry_name, true);
542  pl_sublist.modifyParameterList(valid_pl_sublist, depth-1);
543  }
544  }
545  }
546 }
547 
548 
550  const bool left_to_right)
551 {
552  // We do a breadth-first traversal of `valid_pl` and store references to all of the sublists
553  // in `valid_pl` in a deque with a matching deque for `this`.
554  std::deque<std::reference_wrapper<ParameterList>> refs, valid_refs, tmp, valid_tmp;
555  tmp.push_back(*this);
556  valid_tmp.push_back(valid_pl);
557  while (!valid_tmp.empty()){
558  ParameterList &cur_node = tmp.front();
559  ParameterList &valid_cur_node = valid_tmp.front();
560  tmp.pop_front();
561  valid_tmp.pop_front();
562  refs.push_back(cur_node);
563  valid_refs.push_back(valid_cur_node);
564  // Look for all sublists in valid_tmp
565  for (auto itr = valid_cur_node.begin(); itr != valid_cur_node.end(); ++itr){
566  const std::string &entry_name = itr->first;
567  if (valid_cur_node.isSublist(entry_name)){
568  const ParameterEntry &cur_entry = itr->second;
569  ParameterList &valid_cur_node_sublist = valid_cur_node.sublist(entry_name);
570  if (!valid_cur_node_sublist.disableRecursiveReconciliation_){
572  !cur_node.isSublist(entry_name), Exceptions::InvalidParameterName
573  ,"Error, the parameter {name=\"" << entry_name <<"\","
574  "type=\"" << cur_entry.getAny(false).typeName() << "\""
575  ",value=\"" << filterValueToString(cur_entry) << "\"}"
576  "\nin the parameter (sub)list \"" <<cur_node.name() << "\""
577  "\nwas not found in the list of parameters during reconciliation."
578  "\n\nThe parameters and types are:\n"
579  <<cur_node.currentParametersString()
580  );
581  if (left_to_right){
582  valid_tmp.push_back(valid_cur_node_sublist);
583  tmp.push_back(cur_node.sublist(entry_name));
584  } else{
585  valid_tmp.push_front(valid_cur_node_sublist);
586  tmp.push_front(cur_node.sublist(entry_name));
587  }
588  }
589  }
590  }
591  }
592  // We now apply the reconciliation from the bottom to the top of the parameter lists by
593  // traversing the deques from the back to the front.
595  std::deque<std::reference_wrapper<ParameterList>>::reverse_iterator ref, valid_ref;
596  for(ref = refs.rbegin(), valid_ref = valid_refs.rbegin();
597  ref != refs.rend() && valid_ref != valid_refs.rend();
598  ++ref, ++valid_ref){
599  if (nonnull(modifier = valid_ref->get().getModifier())) {
600  modifier->reconcile(ref->get());
601  }
602  }
603 }
604 
605 
607  ParameterList const& validParamList,
608  int const depth
609  )
610 {
611  typedef std::deque<ListPlusValidList> sublist_list_t;
612 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
614  OSTab tab(out);
615  *out << "\n*** Entering ParameterList::validateParametersAndSetDefaults(...) "
616  "for this->name()=\""<<this->name()<<"\"...\n";
617 #endif
618  //
619  // A) loop through and validate the parameters at this level.
620  //
621  // Here we generate a list of sublists that we will search next
622  //
623  sublist_list_t sublist_list;
624  {
625  Iterator itr;
626  for (itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr) {
627  const std::string &entryName = this->name(itr);
628  ParameterEntry &theEntry = this->nonconstEntry(itr);
629 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
630  OSTab tab(out);
631  *out << "\nentryName=\""<<entryName<<"\"\n";
632 #endif
633  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
636  ,"Error, the parameter {name=\""<<entryName<<"\","
637  "type=\""<<theEntry.getAny(false).typeName()<<"\""
638  ",value=\""<<filterValueToString(theEntry)<<"\"}"
639  "\nin the parameter (sub)list \""<<this->name()<<"\""
640  "\nwas not found in the list of valid parameters!"
641  "\n\nThe valid parameters and types are:\n"
642  <<validParamList.currentParametersString()
643  );
645  if (nonnull(validator=validEntry->validator())) {
646  validator->validateAndModify(entryName, this->name(), &theEntry);
647  theEntry.setValidator(validator);
648  }
649  else {
650  const bool validType =
651  ( validEntry!=NULL
652  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
653  : false
654  );
657  ,"Error, the parameter {name=\""<<entryName<<"\","
658  "type=\""<<theEntry.getAny(false).typeName()<<"\""
659  ",value=\""<<filterValueToString(theEntry)<<"\"}"
660  "\nin the parameter (sub)list \""<<this->name()<<"\""
661  "\nexists in the list of valid parameters but has the wrong type."
662  "\n\nThe correct type is \""
663  << validEntry->getAny(false).typeName() << "\"."
664  );
665  // Note: If there is no validator for this item, then we can not
666  // validate the value of the parameter, only its type!
667  }
668  if( theEntry.isList() && depth > 0 ) {
669  sublist_list.push_back(
670  ListPlusValidList(
671  &getValue<ParameterList>(theEntry),
672  &getValue<ParameterList>(*validEntry)
673  )
674  );
675  }
676  }
677  }
678  //
679  // B) Loop through the valid parameters at this level that are not set in
680  // *this, and set their defaults.
681  //
682  {
683  ConstIterator itr;
684  for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
685  const std::string &validEntryName = validParamList.name(itr);
686  const ParameterEntry &validEntry = validParamList.entry(itr);
687  const ParameterEntry *theEntry = this->getEntryPtr(validEntryName);
688  if (!theEntry) {
689  // This entry does not exist, so add it. Here we will only set the
690  // value of the entry and its validator and and leave off the
691  // documentation. The reason that the validator is set is so that it
692  // can be used to extract and validate entries in the transformed list
693  // *this without having to refer back to the valid parameter list.
694  ParameterEntry newEntry;
695  newEntry.setAnyValue(
696  validEntry.getAny(),
697  true // isDefault
698  );
699  newEntry.setValidator(validEntry.validator());
700  this->setEntry(validEntryName,newEntry);
701  }
702  }
703  }
704  //
705  // C) Loop through the sublists and validate their parameters and set their
706  // defaults!
707  //
708  for (
709  sublist_list_t::iterator sl_itr = sublist_list.begin();
710  sl_itr != sublist_list.end();
711  ++sl_itr
712  )
713  {
714  if (!sl_itr->validList->disableRecursiveValidation_) {
715  sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
716  }
717  }
718 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
719  *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
720  "for this->name()=\""<<this->name()<<"\"...\n";
721 #endif
722 }
723 
724 
725 // private
726 
727 
728 void ParameterList::updateSubListNames(int depth)
729 {
730  const std::string this_name = this->name();
731  Iterator itr;
732  for( itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr ) {
733  const std::string &entryName = this->name(itr);
734  const ParameterEntry &theEntry = this->entry(itr);
735  if(theEntry.isList()) {
736  ParameterList &sublistEntry = getValue<ParameterList>(theEntry);
737  sublistEntry.setName(this_name+std::string("->")+entryName);
738  if(depth > 0)
739  sublistEntry.updateSubListNames(depth-1);
740  }
741  }
742 }
743 
744 
745 void ParameterList::validateEntryExists(
746  const std::string & /*funcName*/, const std::string &name_in,
747  const ParameterEntry *entry_in
748  ) const
749 {
751  entry_in==NULL, Exceptions::InvalidParameterName
752  ,"Error! The parameter \""<<name_in<<"\" does not exist"\
753  "\nin the parameter (sub)list \""<<this->name()<<"\"."
754  "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
755  << this->currentParametersString()
756  );
757 }
758 
759 
760 void ParameterList::validateEntryIsList(
761  const std::string &name_in, const ParameterEntry &entry_in
762  ) const
763 {
765  !entry_in.isList(), Exceptions::InvalidParameterType
766  ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
767  <<entry_in.getAny(false).typeName()<<"\"!" );
768 }
769 
770 
771 void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
772  const std::string &sublist_name, const bool mustAlreadyExist) const
773 {
775  mustAlreadyExist, Exceptions::InvalidParameterName
776  ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
777  );
778 }
779 
780 
781 } // namespace Teuchos
782 
783 
784 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
785 {
786  // Check that the top-level names of the two parameter lists are the same
787  //const std::string &paramListName1 = list1.name();
788  //const std::string &paramListName2 = list2.name();
789  //if ( paramListName1 != paramListName2 ) {
790  // return false;
791  //}
792  if (!Teuchos::haveSameModifiers(list1, list2)){
793  return false;
794  }
795  ParameterList::ConstIterator itr1, itr2;
796  for(
797  itr1 = list1.begin(), itr2 = list2.begin();
798  itr1 != list1.end() && itr2 != list2.end();
799  ++itr1, ++itr2
800  )
801  {
802  const std::string &entryName1 = list1.name(itr1);
803  const std::string &entryName2 = list2.name(itr2);
804  const ParameterEntry &entry1 = list1.entry(itr1);
805  const ParameterEntry &entry2 = list2.entry(itr2);
806  if( entryName1 != entryName2 ) {
807  return false;
808  }
809  else if( entry1 != entry2 ) {
810  return false;
811  }
812  // Note that the above statement automatically recursively compares the
813  // sublists since ParameterList objects are stored in the 'any' variable
814  // held by the ParameterEntry object and this same comparison operator will
815  // be used.
816  }
817  // Check that the two parameter lists are the same length:
818  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
819  return false;
820  }
821  return true;
822 }
823 
824 
825 bool Teuchos::haveSameModifiers(const ParameterList &list1, const ParameterList &list2) {
826  // Check that the modifiers are the same
827  const RCP<const ParameterListModifier> &modifier1 = list1.getModifier();
828  const RCP<const ParameterListModifier> &modifier2 = list2.getModifier();
829  // Compare the modifiers.
830  const bool modifier1_is_null = is_null(modifier1);
831  const bool modifier2_is_null = is_null(modifier2);
832  if( modifier1_is_null || modifier2_is_null ){
833  if ( modifier1_is_null != modifier2_is_null ){
834  return false;
835  }
836  } else if ( *modifier1 != *modifier2 ){
837  return false;
838  }
839  // Now look for more sublists
840  ParameterList::ConstIterator itr1, itr2;
841  for(
842  itr1 = list1.begin(), itr2 = list2.begin();
843  itr1 != list1.end() && itr2 != list2.end();
844  ++itr1, ++itr2
845  )
846  {
847  // Check the modifiers in each sublist.
848  const ParameterEntry &entry1 = itr1->second;
849  const ParameterEntry &entry2 = itr2->second;
850  if (entry1.isList() && entry2.isList()){
851  if ( !haveSameModifiers( Teuchos::getValue<ParameterList>(entry1),
852  Teuchos::getValue<ParameterList>(entry2) ) ){
853  return false;
854  }
855  }
856  }
857  return true;
858 }
859 
860 
861 bool Teuchos::haveSameValues( const ParameterList& list1, const ParameterList& list2, bool verbose )
862 {
863  // Check that the top-level names of the two parameter lists are the same
864  //const std::string &paramListName1 = list1.name();
865  //const std::string &paramListName2 = list2.name();
866  //if ( paramListName1 != paramListName2 ) {
867  // return false;
868  //}
869  ParameterList::ConstIterator itr1, itr2;
870  for(
871  itr1 = list1.begin(), itr2 = list2.begin();
872  itr1 != list1.end() && itr2 != list2.end();
873  ++itr1, ++itr2
874  )
875  {
876  const std::string &entryName1 = list1.name(itr1);
877  const std::string &entryName2 = list2.name(itr2);
878  const ParameterEntry &entry1 = list1.entry(itr1);
879  const ParameterEntry &entry2 = list2.entry(itr2);
880  if( entryName1 != entryName2 ) {
881  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
882  return false;
883  }
884  if( entry1.isList() && entry2.isList() ) {
885  if (
887  getValue<ParameterList>(entry1),
888  getValue<ParameterList>(entry2),
889  verbose)
890  )
891  {
892  // Note: Above we cast to a non-const ParameterList even through we
893  // only need a const ParameterList. We have to do this since a
894  // non-const ParameterList is always added initially which determines
895  // the value.
896  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
897  return false;
898  }
899  }
900  else {
901  if( entry1.getAny() != entry2.getAny() ) {
902  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
903  return false;
904  }
905  }
906  }
907  // Check that the two parameter lists are the same length:
908  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
909  if (verbose) std::cerr << "lists are not the same size\n";
910  return false;
911  }
912  return true;
913 }
914 
915 
916 bool Teuchos::haveSameValuesSorted( const ParameterList& list1, const ParameterList& list2, bool verbose )
917 {
918  // Check that the top-level names of the two parameter lists are the same
919  //const std::string &paramListName1 = list1.name();
920  //const std::string &paramListName2 = list2.name();
921  //if ( paramListName1 != paramListName2 ) {
922  // return false;
923  //}
924  ParameterList::ConstIterator itr1, itr2;
925  Array<std::string> arr1, arr2;
926  for(itr1 = list1.begin(); itr1 != list1.end(); ++itr1){
927  arr1.push_back(list1.name(itr1));
928  }
929  for(itr2 = list2.begin(); itr2 != list2.end(); ++itr2){
930  arr2.push_back(list2.name(itr2));
931  }
932  // Check that the two parameter lists are the same length:
933  if (arr1.size() != arr2.size()) {
934  if (verbose) std::cerr << "lists are not the same size\n";
935  return false;
936  }
937  std::sort(arr1.begin(), arr1.end());
938  std::sort(arr2.begin(), arr2.end());
939  Array<std::string>::iterator iarr1, iarr2;
940  for(
941  iarr1 = arr1.begin(), iarr2 = arr2.begin();
942  iarr1 != arr1.end() && iarr2 != arr2.end();
943  ++iarr1, ++iarr2
944  )
945  {
946  const std::string &entryName1 = *iarr1;
947  const std::string &entryName2 = *iarr2;
948  const ParameterEntry &entry1 = list1.getEntry(entryName1);
949  const ParameterEntry &entry2 = list2.getEntry(entryName2);
950  if( entryName1 != entryName2 ) {
951  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
952  return false;
953  }
954  if( entry1.isList() && entry2.isList() ) {
955  if (
957  getValue<ParameterList>(entry1),
958  getValue<ParameterList>(entry2),
959  verbose)
960  )
961  {
962  // Note: Above we cast to a non-const ParameterList even through we
963  // only need a const ParameterList. We have to do this since a
964  // non-const ParameterList is always added initially which determines
965  // the value.
966  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
967  return false;
968  }
969  }
970  else {
971  if( entry1.getAny() != entry2.getAny() ) {
972  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
973  return false;
974  }
975  }
976  }
977  return true;
978 }
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.