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  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 {
179  return *this;
180 }
181 
182 
184 {
186  return *this;
187 }
188 
189 
191 {
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  );
700  if (nonnull(validator=validEntry.validator())) {
701 #if defined(HAVE_TEUCHOS_MODIFY_DEFAULTS_DURING_VALIDATION)
702  validEntry.validator()->validateAndModify(this->name(itr), validEntryName, &newEntry);
703  // validateAndModify changes the default status so we reset it
704  newEntry.setAnyValue(newEntry.getAny(), true);
705 #endif
706  newEntry.setValidator(validator);
707  }
708  this->setEntry(validEntryName,newEntry);
709  }
710  }
711  }
712  //
713  // C) Loop through the sublists and validate their parameters and set their
714  // defaults!
715  //
716  for (
717  sublist_list_t::iterator sl_itr = sublist_list.begin();
718  sl_itr != sublist_list.end();
719  ++sl_itr
720  )
721  {
722  if (!sl_itr->validList->disableRecursiveValidation_) {
723  sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
724  }
725  }
726 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
727  *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
728  "for this->name()=\""<<this->name()<<"\"...\n";
729 #endif
730 }
731 
732 
733 // private
734 
735 
737 {
738  const std::string this_name = this->name();
739  Iterator itr;
740  for( itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr ) {
741  const std::string &entryName = this->name(itr);
742  const ParameterEntry &theEntry = this->entry(itr);
743  if(theEntry.isList()) {
744  ParameterList &sublistEntry = getValue<ParameterList>(theEntry);
745  sublistEntry.setName(this_name+std::string("->")+entryName);
746  if(depth > 0)
747  sublistEntry.updateSubListNames(depth-1);
748  }
749  }
750 }
751 
752 
754  const std::string & /*funcName*/, const std::string &name_in,
755  const ParameterEntry *entry_in
756  ) const
757 {
759  entry_in==NULL, Exceptions::InvalidParameterName
760  ,"Error! The parameter \""<<name_in<<"\" does not exist"\
761  "\nin the parameter (sub)list \""<<this->name()<<"\"."
762  "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
763  << this->currentParametersString()
764  );
765 }
766 
767 
769  const std::string &name_in, const ParameterEntry &entry_in
770  ) const
771 {
774  ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
775  <<entry_in.getAny(false).typeName()<<"\"!" );
776 }
777 
778 
779 void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
780  const std::string &sublist_name, const bool mustAlreadyExist) const
781 {
783  mustAlreadyExist, Exceptions::InvalidParameterName
784  ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
785  );
786 }
787 
788 
789 } // namespace Teuchos
790 
791 
792 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
793 {
794  // Check that the top-level names of the two parameter lists are the same
795  //const std::string &paramListName1 = list1.name();
796  //const std::string &paramListName2 = list2.name();
797  //if ( paramListName1 != paramListName2 ) {
798  // return false;
799  //}
800  if (!Teuchos::haveSameModifiers(list1, list2)){
801  return false;
802  }
803  ParameterList::ConstIterator itr1, itr2;
804  for(
805  itr1 = list1.begin(), itr2 = list2.begin();
806  itr1 != list1.end() && itr2 != list2.end();
807  ++itr1, ++itr2
808  )
809  {
810  const std::string &entryName1 = list1.name(itr1);
811  const std::string &entryName2 = list2.name(itr2);
812  const ParameterEntry &entry1 = list1.entry(itr1);
813  const ParameterEntry &entry2 = list2.entry(itr2);
814  if( entryName1 != entryName2 ) {
815  return false;
816  }
817  else if( entry1 != entry2 ) {
818  return false;
819  }
820  // Note that the above statement automatically recursively compares the
821  // sublists since ParameterList objects are stored in the 'any' variable
822  // held by the ParameterEntry object and this same comparison operator will
823  // be used.
824  }
825  // Check that the two parameter lists are the same length:
826  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
827  return false;
828  }
829  return true;
830 }
831 
832 
833 bool Teuchos::haveSameModifiers(const ParameterList &list1, const ParameterList &list2) {
834  // Check that the modifiers are the same
835  const RCP<const ParameterListModifier> &modifier1 = list1.getModifier();
836  const RCP<const ParameterListModifier> &modifier2 = list2.getModifier();
837  // Compare the modifiers.
838  const bool modifier1_is_null = is_null(modifier1);
839  const bool modifier2_is_null = is_null(modifier2);
840  if( modifier1_is_null || modifier2_is_null ){
841  if ( modifier1_is_null != modifier2_is_null ){
842  return false;
843  }
844  } else if ( *modifier1 != *modifier2 ){
845  return false;
846  }
847  // Now look for more sublists
848  ParameterList::ConstIterator itr1, itr2;
849  for(
850  itr1 = list1.begin(), itr2 = list2.begin();
851  itr1 != list1.end() && itr2 != list2.end();
852  ++itr1, ++itr2
853  )
854  {
855  // Check the modifiers in each sublist.
856  const ParameterEntry &entry1 = itr1->second;
857  const ParameterEntry &entry2 = itr2->second;
858  if (entry1.isList() && entry2.isList()){
859  if ( !haveSameModifiers( Teuchos::getValue<ParameterList>(entry1),
860  Teuchos::getValue<ParameterList>(entry2) ) ){
861  return false;
862  }
863  }
864  }
865  return true;
866 }
867 
868 
869 bool Teuchos::haveSameValues( const ParameterList& list1, const ParameterList& list2, bool verbose )
870 {
871  // Check that the top-level names of the two parameter lists are the same
872  //const std::string &paramListName1 = list1.name();
873  //const std::string &paramListName2 = list2.name();
874  //if ( paramListName1 != paramListName2 ) {
875  // return false;
876  //}
877  ParameterList::ConstIterator itr1, itr2;
878  for(
879  itr1 = list1.begin(), itr2 = list2.begin();
880  itr1 != list1.end() && itr2 != list2.end();
881  ++itr1, ++itr2
882  )
883  {
884  const std::string &entryName1 = list1.name(itr1);
885  const std::string &entryName2 = list2.name(itr2);
886  const ParameterEntry &entry1 = list1.entry(itr1);
887  const ParameterEntry &entry2 = list2.entry(itr2);
888  if( entryName1 != entryName2 ) {
889  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
890  return false;
891  }
892  if( entry1.isList() && entry2.isList() ) {
893  if (
895  getValue<ParameterList>(entry1),
896  getValue<ParameterList>(entry2),
897  verbose)
898  )
899  {
900  // Note: Above we cast to a non-const ParameterList even through we
901  // only need a const ParameterList. We have to do this since a
902  // non-const ParameterList is always added initially which determines
903  // the value.
904  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
905  return false;
906  }
907  }
908  else {
909  if( entry1.getAny() != entry2.getAny() ) {
910  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
911  return false;
912  }
913  }
914  }
915  // Check that the two parameter lists are the same length:
916  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
917  if (verbose) std::cerr << "lists are not the same size\n";
918  return false;
919  }
920  return true;
921 }
922 
923 
924 bool Teuchos::haveSameValuesSorted( const ParameterList& list1, const ParameterList& list2, bool verbose )
925 {
926  // Check that the top-level names of the two parameter lists are the same
927  //const std::string &paramListName1 = list1.name();
928  //const std::string &paramListName2 = list2.name();
929  //if ( paramListName1 != paramListName2 ) {
930  // return false;
931  //}
932  ParameterList::ConstIterator itr1, itr2;
933  Array<std::string> arr1, arr2;
934  for(itr1 = list1.begin(); itr1 != list1.end(); ++itr1){
935  arr1.push_back(list1.name(itr1));
936  }
937  for(itr2 = list2.begin(); itr2 != list2.end(); ++itr2){
938  arr2.push_back(list2.name(itr2));
939  }
940  // Check that the two parameter lists are the same length:
941  if (arr1.size() != arr2.size()) {
942  if (verbose) std::cerr << "lists are not the same size\n";
943  return false;
944  }
945  std::sort(arr1.begin(), arr1.end());
946  std::sort(arr2.begin(), arr2.end());
947  Array<std::string>::iterator iarr1, iarr2;
948  for(
949  iarr1 = arr1.begin(), iarr2 = arr2.begin();
950  iarr1 != arr1.end() && iarr2 != arr2.end();
951  ++iarr1, ++iarr2
952  )
953  {
954  const std::string &entryName1 = *iarr1;
955  const std::string &entryName2 = *iarr2;
956  const ParameterEntry &entry1 = list1.getEntry(entryName1);
957  const ParameterEntry &entry2 = list2.getEntry(entryName2);
958  if( entryName1 != entryName2 ) {
959  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
960  return false;
961  }
962  if( entry1.isList() && entry2.isList() ) {
963  if (
965  getValue<ParameterList>(entry1),
966  getValue<ParameterList>(entry2),
967  verbose)
968  )
969  {
970  // Note: Above we cast to a non-const ParameterList even through we
971  // only need a const ParameterList. We have to do this since a
972  // non-const ParameterList is always added initially which determines
973  // the value.
974  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
975  return false;
976  }
977  }
978  else {
979  if( entry1.getAny() != entry2.getAny() ) {
980  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
981  return false;
982  }
983  }
984  }
985  return true;
986 }
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...
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
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.