Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_ParameterList.cpp
Go to the documentation of this file.
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"
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_;
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_;
117  modifier_ = source.modifier_;
118  return *this;
119 }
120 
121 
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 {
175  return *this;
176 }
177 
178 
180 {
182  return *this;
183 }
184 
185 
187 {
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 bool showDefault = printOptions.showDefault();
353  const std::string linePrefix(indent,' ');
355  out = getFancyOStream(rcp(&os,false));
356  OSTab tab(out,indent);
357  if (this->begin() == this->end()) {
358  *out <<"[empty list]" << std::endl;
359  }
360  else {
361  // Print parameters first
362  for (ConstIterator i = this->begin(); i != this->end(); ++i)
363  {
364  const std::string &name_i = this->name(i);
365  const ParameterEntry &entry_i = entry(i);
367  validator = entry_i.validator();
368  if(entry_i.isList())
369  continue;
370  if(!showDefault && entry_i.isDefault())
371  continue;
372  *out << name_i;
373  const std::string &docString = entry_i.docString();
374  if(showTypes)
375  *out << " : " << entry_i.getAny(false).typeName();
376  *out << " = "; entry_i.leftshift(os,showFlags); *out << std::endl;
377  if (showDoc) {
378  if (nonnull(validator)) {
379  validator->printDoc(docString,OSTab(os).o());
380  }
381  else if (docString.length()) {
382  StrUtils::printLines(OSTab(out).o(),"# ",docString);
383  }
384  }
385  }
386  // Print sublists second
387  for (ConstIterator i = this->begin(); i != this->end(); ++i)
388  {
389  const ParameterEntry &entry_i = entry(i);
390  if(!entry_i.isList())
391  continue;
392  const std::string &docString = entry_i.docString();
393  const std::string &name_i = this->name(i);
394  *out << name_i << " -> " << std::endl;
395  if( docString.length() && showDoc ) {
396  StrUtils::printLines(OSTab(out).o(),"# ",docString);
397  }
398  getValue<ParameterList>(entry_i).print(OSTab(out).o(), printOptions.copy().indent(0));
399  }
400  }
401  return os;
402 }
403 
404 
405 std::ostream& ParameterList::print(std::ostream& os, int indent, bool showTypes, bool showFlags, bool showDefault) const
406 {
407  return this->print(os,PrintOptions().indent(indent).showTypes(showTypes).showFlags(showFlags).showDefault(showDefault));
408 }
409 
410 
412  ParameterList const& validParamList,
413  int const depth,
414  EValidateUsed const validateUsed,
415  EValidateDefaults const validateDefaults
416  ) const
417 {
418  typedef std::deque<ListPlusValidList> sublist_list_t;
419 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
421  OSTab tab(out);
422  *out << "\n*** Entering ParameterList::validateParameters(...) for "
423  "this->name()=\""<<this->name()<<"\"...\n";
424 #endif
425  //
426  // First loop through and validate the parameters at this level.
427  //
428  // Here we generate a list of sublists that we will search next
429  //
430  sublist_list_t sublist_list;
431  ConstIterator itr;
432  for (itr = this->begin(); itr != this->end(); ++itr) {
433  const std::string &entryName = this->name(itr);
434  const ParameterEntry &theEntry = this->entry(itr);
435 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
436  OSTab tab(out);
437  *out << "\nentryName=\""<<entryName<<"\"\n";
438 #endif
439  if(
440  ( theEntry.isUsed() && validateUsed!=VALIDATE_USED_ENABLED )
441  ||
442  ( theEntry.isDefault() && validateDefaults!=VALIDATE_DEFAULTS_ENABLED )
443  )
444  {
445  continue;
446  }
447  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
450  ,"Error, the parameter {name=\""<<entryName<<"\","
451  "type=\""<<theEntry.getAny(false).typeName()<<"\""
452  ",value=\""<<filterValueToString(theEntry)<<"\"}"
453  "\nin the parameter (sub)list \""<<this->name()<<"\""
454  "\nwas not found in the list of valid parameters!"
455  "\n\nThe valid parameters and types are:\n"
456  <<validParamList.currentParametersString()
457  );
459  if (nonnull(validator=validEntry->validator())) {
460  validator->validate(theEntry, entryName, this->name());
461  }
462  else {
463  const bool validType =
464  ( validEntry!=NULL
465  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
466  : false
467  );
470  ,"Error, the parameter {name=\""<<entryName<<"\","
471  "type=\""<<theEntry.getAny(false).typeName()<<"\""
472  ",value=\""<<filterValueToString(theEntry)<<"\"}"
473  "\nin the parameter (sub)list \""<<this->name()<<"\""
474  "\nexists in the list of valid parameters but has the wrong type."
475  "\n\nThe correct type is \""
476  << validEntry->getAny(false).typeName() << "\"."
477  );
478  }
479  if( theEntry.isList() && depth > 0 ) {
480  sublist_list.push_back(
481  ListPlusValidList(
482  &getValue<ParameterList>(theEntry),&getValue<ParameterList>(*validEntry)
483  )
484  );
485  }
486  }
487  //
488  // Now loop through the sublists and validate their parameters
489  //
490  for(
491  sublist_list_t::const_iterator sl_itr = sublist_list.begin();
492  sl_itr != sublist_list.end();
493  ++sl_itr
494  )
495  {
496  if (!sl_itr->validList->disableRecursiveValidation_) {
497  sl_itr->list->validateParameters(
498  *sl_itr->validList
499  ,depth-1
500  ,validateUsed
501  ,validateDefaults
502  );
503  }
504  }
505 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
506  *out << "\n*** Existing ParameterList::validateParameters(...) for "
507  "this->name()=\""<<this->name()<<"\"...\n";
508 #endif
509 }
510 
511 
513  int const depth)
514 {
516  if (nonnull(modifier = valid_pl.getModifier())) {
517  modifier->modify(*this, valid_pl);
518  }
519  ConstIterator itr;
520  for (itr = valid_pl.begin(); itr != valid_pl.end(); ++itr){
521  const std::string &entry_name = itr->first;
522  const ParameterEntry &cur_entry = itr->second;
523  if (cur_entry.isList() && depth > 0){
524  ParameterList &valid_pl_sublist = valid_pl.sublist(entry_name, true);
525  if(!valid_pl_sublist.disableRecursiveModification_){
526  const ParameterEntry *validEntry = this->getEntryPtr(entry_name);
529  ,"Error, the parameter {name=\""<<entry_name<<"\","
530  "type=\""<<cur_entry.getAny(false).typeName()<<"\""
531  ",value=\""<<filterValueToString(cur_entry)<<"\"}"
532  "\nin the parameter (sub)list \""<<this->name()<<"\""
533  "\nwas not found in the list of parameters during modification."
534  "\n\nThe parameters and types are:\n"
535  <<this->currentParametersString()
536  );
537  ParameterList &pl_sublist = this->sublist(entry_name, true);
538  pl_sublist.modifyParameterList(valid_pl_sublist, depth-1);
539  }
540  }
541  }
542 }
543 
544 
546  const bool left_to_right)
547 {
548  // We do a breadth-first traversal of `valid_pl` and store references to all of the sublists
549  // in `valid_pl` in a deque with a matching deque for `this`.
550  std::deque<std::reference_wrapper<ParameterList>> refs, valid_refs, tmp, valid_tmp;
551  tmp.push_back(*this);
552  valid_tmp.push_back(valid_pl);
553  while (!valid_tmp.empty()){
554  ParameterList &cur_node = tmp.front();
555  ParameterList &valid_cur_node = valid_tmp.front();
556  tmp.pop_front();
557  valid_tmp.pop_front();
558  refs.push_back(cur_node);
559  valid_refs.push_back(valid_cur_node);
560  // Look for all sublists in valid_tmp
561  for (auto itr = valid_cur_node.begin(); itr != valid_cur_node.end(); ++itr){
562  const std::string &entry_name = itr->first;
563  if (valid_cur_node.isSublist(entry_name)){
564  const ParameterEntry &cur_entry = itr->second;
565  ParameterList &valid_cur_node_sublist = valid_cur_node.sublist(entry_name);
566  if (!valid_cur_node_sublist.disableRecursiveReconciliation_){
568  !cur_node.isSublist(entry_name), Exceptions::InvalidParameterName
569  ,"Error, the parameter {name=\"" << entry_name <<"\","
570  "type=\"" << cur_entry.getAny(false).typeName() << "\""
571  ",value=\"" << filterValueToString(cur_entry) << "\"}"
572  "\nin the parameter (sub)list \"" <<cur_node.name() << "\""
573  "\nwas not found in the list of parameters during reconciliation."
574  "\n\nThe parameters and types are:\n"
575  <<cur_node.currentParametersString()
576  );
577  if (left_to_right){
578  valid_tmp.push_back(valid_cur_node_sublist);
579  tmp.push_back(cur_node.sublist(entry_name));
580  } else{
581  valid_tmp.push_front(valid_cur_node_sublist);
582  tmp.push_front(cur_node.sublist(entry_name));
583  }
584  }
585  }
586  }
587  }
588  // We now apply the reconciliation from the bottom to the top of the parameter lists by
589  // traversing the deques from the back to the front.
591  std::deque<std::reference_wrapper<ParameterList>>::reverse_iterator ref, valid_ref;
592  for(ref = refs.rbegin(), valid_ref = valid_refs.rbegin();
593  ref != refs.rend() && valid_ref != valid_refs.rend();
594  ++ref, ++valid_ref){
595  if (nonnull(modifier = valid_ref->get().getModifier())) {
596  modifier->reconcile(ref->get());
597  }
598  }
599 }
600 
601 
603  ParameterList const& validParamList,
604  int const depth
605  )
606 {
607  typedef std::deque<ListPlusValidList> sublist_list_t;
608 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
610  OSTab tab(out);
611  *out << "\n*** Entering ParameterList::validateParametersAndSetDefaults(...) "
612  "for this->name()=\""<<this->name()<<"\"...\n";
613 #endif
614  //
615  // A) loop through and validate the parameters at this level.
616  //
617  // Here we generate a list of sublists that we will search next
618  //
619  sublist_list_t sublist_list;
620  {
621  Iterator itr;
622  for (itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr) {
623  const std::string &entryName = this->name(itr);
624  ParameterEntry &theEntry = this->nonconstEntry(itr);
625 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
626  OSTab tab(out);
627  *out << "\nentryName=\""<<entryName<<"\"\n";
628 #endif
629  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
632  ,"Error, the parameter {name=\""<<entryName<<"\","
633  "type=\""<<theEntry.getAny(false).typeName()<<"\""
634  ",value=\""<<filterValueToString(theEntry)<<"\"}"
635  "\nin the parameter (sub)list \""<<this->name()<<"\""
636  "\nwas not found in the list of valid parameters!"
637  "\n\nThe valid parameters and types are:\n"
638  <<validParamList.currentParametersString()
639  );
641  if (nonnull(validator=validEntry->validator())) {
642  validator->validateAndModify(entryName, this->name(), &theEntry);
643  theEntry.setValidator(validator);
644  }
645  else {
646  const bool validType =
647  ( validEntry!=NULL
648  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
649  : false
650  );
653  ,"Error, the parameter {name=\""<<entryName<<"\","
654  "type=\""<<theEntry.getAny(false).typeName()<<"\""
655  ",value=\""<<filterValueToString(theEntry)<<"\"}"
656  "\nin the parameter (sub)list \""<<this->name()<<"\""
657  "\nexists in the list of valid parameters but has the wrong type."
658  "\n\nThe correct type is \""
659  << validEntry->getAny(false).typeName() << "\"."
660  );
661  // Note: If there is no validator for this item, then we can not
662  // validate the value of the parameter, only its type!
663  }
664  if( theEntry.isList() && depth > 0 ) {
665  sublist_list.push_back(
666  ListPlusValidList(
667  &getValue<ParameterList>(theEntry),
668  &getValue<ParameterList>(*validEntry)
669  )
670  );
671  }
672  }
673  }
674  //
675  // B) Loop through the valid parameters at this level that are not set in
676  // *this, and set their defaults.
677  //
678  {
679  ConstIterator itr;
680  for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
681  const std::string &validEntryName = validParamList.name(itr);
682  const ParameterEntry &validEntry = validParamList.entry(itr);
683  const ParameterEntry *theEntry = this->getEntryPtr(validEntryName);
684  if (!theEntry) {
685  // This entry does not exist, so add it. Here we will only set the
686  // value of the entry and its validator and and leave off the
687  // documentation. The reason that the validator is set is so that it
688  // can be used to extract and validate entries in the transformed list
689  // *this without having to refer back to the valid parameter list.
690  ParameterEntry newEntry;
691  newEntry.setAnyValue(
692  validEntry.getAny(),
693  true // isDefault
694  );
695  newEntry.setValidator(validEntry.validator());
696  this->setEntry(validEntryName,newEntry);
697  }
698  }
699  }
700  //
701  // C) Loop through the sublists and validate their parameters and set their
702  // defaults!
703  //
704  for (
705  sublist_list_t::iterator sl_itr = sublist_list.begin();
706  sl_itr != sublist_list.end();
707  ++sl_itr
708  )
709  {
710  if (!sl_itr->validList->disableRecursiveValidation_) {
711  sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
712  }
713  }
714 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
715  *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
716  "for this->name()=\""<<this->name()<<"\"...\n";
717 #endif
718 }
719 
720 
721 // private
722 
723 
725 {
726  const std::string this_name = this->name();
727  Iterator itr;
728  for( itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr ) {
729  const std::string &entryName = this->name(itr);
730  const ParameterEntry &theEntry = this->entry(itr);
731  if(theEntry.isList()) {
732  ParameterList &sublistEntry = getValue<ParameterList>(theEntry);
733  sublistEntry.setName(this_name+std::string("->")+entryName);
734  if(depth > 0)
735  sublistEntry.updateSubListNames(depth-1);
736  }
737  }
738 }
739 
740 
742  const std::string & /*funcName*/, const std::string &name_in,
743  const ParameterEntry *entry_in
744  ) const
745 {
747  entry_in==NULL, Exceptions::InvalidParameterName
748  ,"Error! The parameter \""<<name_in<<"\" does not exist"\
749  "\nin the parameter (sub)list \""<<this->name()<<"\"."
750  "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
751  << this->currentParametersString()
752  );
753 }
754 
755 
757  const std::string &name_in, const ParameterEntry &entry_in
758  ) const
759 {
762  ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
763  <<entry_in.getAny(false).typeName()<<"\"!" );
764 }
765 
766 
767 void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
768  const std::string &sublist_name, const bool mustAlreadyExist) const
769 {
771  mustAlreadyExist, Exceptions::InvalidParameterName
772  ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
773  );
774 }
775 
776 
777 } // namespace Teuchos
778 
779 
780 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
781 {
782  // Check that the top-level names of the two parameter lists are the same
783  //const std::string &paramListName1 = list1.name();
784  //const std::string &paramListName2 = list2.name();
785  //if ( paramListName1 != paramListName2 ) {
786  // return false;
787  //}
788  if (!Teuchos::haveSameModifiers(list1, list2)){
789  return false;
790  }
791  ParameterList::ConstIterator itr1, itr2;
792  for(
793  itr1 = list1.begin(), itr2 = list2.begin();
794  itr1 != list1.end() && itr2 != list2.end();
795  ++itr1, ++itr2
796  )
797  {
798  const std::string &entryName1 = list1.name(itr1);
799  const std::string &entryName2 = list2.name(itr2);
800  const ParameterEntry &entry1 = list1.entry(itr1);
801  const ParameterEntry &entry2 = list2.entry(itr2);
802  if( entryName1 != entryName2 ) {
803  return false;
804  }
805  else if( entry1 != entry2 ) {
806  return false;
807  }
808  // Note that the above statement automatically recursively compare the
809  // sublists since ParameterList objects are stored in the 'any' variable
810  // held by the ParameterEntry object and this same comparison operator will
811  // be used.
812  }
813  // Check that the two parameter lists are the same length:
814  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
815  return false;
816  }
817  return true;
818 }
819 
820 
821 bool Teuchos::haveSameModifiers(const ParameterList &list1, const ParameterList &list2) {
822  // Check that the modifiers are the same
823  ParameterList::ConstIterator itr1, itr2;
824  for(
825  itr1 = list1.begin(), itr2 = list2.begin();
826  itr1 != list1.end() && itr2 != list2.end();
827  ++itr1, ++itr2
828  )
829  {
830  const Teuchos::RCP<const ParameterListModifier> &modifier1 = list1.getModifier();
831  const Teuchos::RCP<const ParameterListModifier> &modifier2 = list2.getModifier();
832  if( modifier1 != modifier2 ) {
833  return false;
834  }
835  const Teuchos::ParameterEntry &entry1 = itr1->second;
836  const Teuchos::ParameterEntry &entry2 = itr2->second;
837  if (entry1.isList() && entry2.isList()){
838  if ( !haveSameModifiers( Teuchos::getValue<ParameterList>(entry1),
839  Teuchos::getValue<ParameterList>(entry2) ) ){
840  return false;
841  }
842  }
843  }
844  return true;
845 }
846 
847 
848 bool Teuchos::haveSameValues( const ParameterList& list1, const ParameterList& list2, bool verbose )
849 {
850  // Check that the top-level names of the two parameter lists are the same
851  //const std::string &paramListName1 = list1.name();
852  //const std::string &paramListName2 = list2.name();
853  //if ( paramListName1 != paramListName2 ) {
854  // return false;
855  //}
856  ParameterList::ConstIterator itr1, itr2;
857  for(
858  itr1 = list1.begin(), itr2 = list2.begin();
859  itr1 != list1.end() && itr2 != list2.end();
860  ++itr1, ++itr2
861  )
862  {
863  const std::string &entryName1 = list1.name(itr1);
864  const std::string &entryName2 = list2.name(itr2);
865  const ParameterEntry &entry1 = list1.entry(itr1);
866  const ParameterEntry &entry2 = list2.entry(itr2);
867  if( entryName1 != entryName2 ) {
868  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
869  return false;
870  }
871  if( entry1.isList() && entry2.isList() ) {
872  if (
874  getValue<ParameterList>(entry1),
875  getValue<ParameterList>(entry2),
876  verbose)
877  )
878  {
879  // Note: Above we cast to a non-const ParameterList even through we
880  // only need a const ParameterList. We have to do this since a
881  // non-const ParameterList is always added initially which determines
882  // the value.
883  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
884  return false;
885  }
886  }
887  else {
888  if( entry1.getAny() != entry2.getAny() ) {
889  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
890  return false;
891  }
892  }
893  }
894  // Check that the two parameter lists are the same length:
895  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
896  if (verbose) std::cerr << "lists are not the same size\n";
897  return false;
898  }
899  return true;
900 }
901 
902 
903 bool Teuchos::haveSameValuesSorted( const ParameterList& list1, const ParameterList& list2, bool verbose )
904 {
905  // Check that the top-level names of the two parameter lists are the same
906  //const std::string &paramListName1 = list1.name();
907  //const std::string &paramListName2 = list2.name();
908  //if ( paramListName1 != paramListName2 ) {
909  // return false;
910  //}
911  ParameterList::ConstIterator itr1, itr2;
912  Array<std::string> arr1, arr2;
913  for(itr1 = list1.begin(); itr1 != list1.end(); ++itr1){
914  arr1.push_back(list1.name(itr1));
915  }
916  for(itr2 = list2.begin(); itr2 != list2.end(); ++itr2){
917  arr2.push_back(list2.name(itr2));
918  }
919  // Check that the two parameter lists are the same length:
920  if (arr1.size() != arr2.size()) {
921  if (verbose) std::cerr << "lists are not the same size\n";
922  return false;
923  }
924  std::sort(arr1.begin(), arr1.end());
925  std::sort(arr2.begin(), arr2.end());
926  Array<std::string>::iterator iarr1, iarr2;
927  for(
928  iarr1 = arr1.begin(), iarr2 = arr2.begin();
929  iarr1 != arr1.end() && iarr2 != arr2.end();
930  ++iarr1, ++iarr2
931  )
932  {
933  const std::string &entryName1 = *iarr1;
934  const std::string &entryName2 = *iarr2;
935  const ParameterEntry &entry1 = list1.getEntry(entryName1);
936  const ParameterEntry &entry2 = list2.getEntry(entryName2);
937  if( entryName1 != entryName2 ) {
938  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
939  return false;
940  }
941  if( entry1.isList() && entry2.isList() ) {
942  if (
944  getValue<ParameterList>(entry1),
945  getValue<ParameterList>(entry2),
946  verbose)
947  )
948  {
949  // Note: Above we cast to a non-const ParameterList even through we
950  // only need a const ParameterList. We have to do this since a
951  // non-const ParameterList is always added initially which determines
952  // the value.
953  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
954  return false;
955  }
956  }
957  else {
958  if( entry1.getAny() != entry2.getAny() ) {
959  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
960  return false;
961  }
962  }
963  }
964  return true;
965 }
void print() const
Print function to use in debugging in a debugger.
void validateEntryIsList(const std::string &name, const ParameterEntry &entry) const
Validate a sublist param is indeed a sublist.
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.
bool disableRecursiveModification_
Modify into list or not.
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.
PrintOptions & showTypes(bool _showTypes)
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.
Iterator nonconstBegin()
An iterator pointing to the first entry.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
void validateEntryExists(const std::string &funcName, const std::string &name, const ParameterEntry *entry) const
Validate that a parameter exists.
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.
bool disableRecursiveReconciliation_
Reconcile into list or not.
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...
basic_OSTab< char > OSTab
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.
PrintOptions & showDefault(bool _showDefault)
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).
Iterator nonconstEnd()
An iterator pointing beyond the last entry.
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.
std::string name_
Name of the (sub)list.
ParameterEntry & nonconstEntry(Iterator i)
Access to ParameterEntry (i.e., returns i-&gt;second)
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.
void updateSubListNames(int depth=0)
Update sublist names recursively.
A list of parameters of arbitrary type.
RCP< const ParameterListModifier > modifier_
void validateMissingSublistMustExist(const std::string &baselist_name, const std::string &sublist_name, const bool mustAlreadyExist) const
Throw a sublist does not exist exception.
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)
params_t params_
Parameter list.
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 operator==(BigUInt< n > const &a, BigUInt< n > const &b)
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...
bool disableRecursiveValidation_
Validate into list or not.
PrintOptions & showFlags(bool _showFlags)
void reconcileParameterList(ParameterList &validParamList, const bool left_to_right=true)
Reconcile a parameter list after validation.
void setModifier(RCP< const ParameterListModifier > const &modifier)
#define TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.