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  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 }
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.
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.
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...
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.
ParameterList & setEntry(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
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.
Ordinal setObj(const std::string &key, const ObjType &obj)
Set (or reset) object by value and return its ordinal index.
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.