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  this->setModifier(modifier);
523  }
524  ConstIterator itr;
525  for (itr = valid_pl.begin(); itr != valid_pl.end(); ++itr){
526  const std::string &entry_name = itr->first;
527  const ParameterEntry &cur_entry = itr->second;
528  if (cur_entry.isList() && depth > 0){
529  ParameterList &valid_pl_sublist = valid_pl.sublist(entry_name, true);
530  if(!valid_pl_sublist.disableRecursiveModification_){
531  const ParameterEntry *validEntry = this->getEntryPtr(entry_name);
534  ,"Error, the parameter {name=\""<<entry_name<<"\","
535  "type=\""<<cur_entry.getAny(false).typeName()<<"\""
536  ",value=\""<<filterValueToString(cur_entry)<<"\"}"
537  "\nin the parameter (sub)list \""<<this->name()<<"\""
538  "\nwas not found in the list of parameters during modification."
539  "\n\nThe parameters and types are:\n"
540  <<this->currentParametersString()
541  );
542  ParameterList &pl_sublist = this->sublist(entry_name, true);
543  pl_sublist.modifyParameterList(valid_pl_sublist, depth-1);
544  }
545  }
546  }
547 }
548 
549 
551  const bool left_to_right)
552 {
553  // We do a breadth-first traversal of `valid_pl` and store references to all of the sublists
554  // in `valid_pl` in a deque with a matching deque for `this`.
555  std::deque<std::reference_wrapper<ParameterList>> refs, valid_refs, tmp, valid_tmp;
556  tmp.push_back(*this);
557  valid_tmp.push_back(valid_pl);
558  while (!valid_tmp.empty()){
559  ParameterList &cur_node = tmp.front();
560  ParameterList &valid_cur_node = valid_tmp.front();
561  tmp.pop_front();
562  valid_tmp.pop_front();
563  refs.push_back(cur_node);
564  valid_refs.push_back(valid_cur_node);
565  // Look for all sublists in valid_tmp
566  for (auto itr = valid_cur_node.begin(); itr != valid_cur_node.end(); ++itr){
567  const std::string &entry_name = itr->first;
568  if (valid_cur_node.isSublist(entry_name)){
569  const ParameterEntry &cur_entry = itr->second;
570  ParameterList &valid_cur_node_sublist = valid_cur_node.sublist(entry_name);
571  if (!valid_cur_node_sublist.disableRecursiveReconciliation_){
573  !cur_node.isSublist(entry_name), Exceptions::InvalidParameterName
574  ,"Error, the parameter {name=\"" << entry_name <<"\","
575  "type=\"" << cur_entry.getAny(false).typeName() << "\""
576  ",value=\"" << filterValueToString(cur_entry) << "\"}"
577  "\nin the parameter (sub)list \"" <<cur_node.name() << "\""
578  "\nwas not found in the list of parameters during reconciliation."
579  "\n\nThe parameters and types are:\n"
580  <<cur_node.currentParametersString()
581  );
582  if (left_to_right){
583  valid_tmp.push_back(valid_cur_node_sublist);
584  tmp.push_back(cur_node.sublist(entry_name));
585  } else{
586  valid_tmp.push_front(valid_cur_node_sublist);
587  tmp.push_front(cur_node.sublist(entry_name));
588  }
589  }
590  }
591  }
592  }
593  // We now apply the reconciliation from the bottom to the top of the parameter lists by
594  // traversing the deques from the back to the front.
596  std::deque<std::reference_wrapper<ParameterList>>::reverse_iterator ref, valid_ref;
597  for(ref = refs.rbegin(), valid_ref = valid_refs.rbegin();
598  ref != refs.rend() && valid_ref != valid_refs.rend();
599  ++ref, ++valid_ref){
600  if (nonnull(modifier = valid_ref->get().getModifier())) {
601  modifier->reconcile(ref->get());
602  }
603  }
604 }
605 
606 
608  ParameterList const& validParamList,
609  int const depth
610  )
611 {
612  typedef std::deque<ListPlusValidList> sublist_list_t;
613 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
615  OSTab tab(out);
616  *out << "\n*** Entering ParameterList::validateParametersAndSetDefaults(...) "
617  "for this->name()=\""<<this->name()<<"\"...\n";
618 #endif
619  //
620  // A) loop through and validate the parameters at this level.
621  //
622  // Here we generate a list of sublists that we will search next
623  //
624  sublist_list_t sublist_list;
625  {
626  Iterator itr;
627  for (itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr) {
628  const std::string &entryName = this->name(itr);
629  ParameterEntry &theEntry = this->nonconstEntry(itr);
630 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
631  OSTab tab(out);
632  *out << "\nentryName=\""<<entryName<<"\"\n";
633 #endif
634  const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
637  ,"Error, the parameter {name=\""<<entryName<<"\","
638  "type=\""<<theEntry.getAny(false).typeName()<<"\""
639  ",value=\""<<filterValueToString(theEntry)<<"\"}"
640  "\nin the parameter (sub)list \""<<this->name()<<"\""
641  "\nwas not found in the list of valid parameters!"
642  "\n\nThe valid parameters and types are:\n"
643  <<validParamList.currentParametersString()
644  );
646  if (nonnull(validator=validEntry->validator())) {
647  validator->validateAndModify(entryName, this->name(), &theEntry);
648  theEntry.setValidator(validator);
649  }
650  else {
651  const bool validType =
652  ( validEntry!=NULL
653  ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
654  : false
655  );
658  ,"Error, the parameter {name=\""<<entryName<<"\","
659  "type=\""<<theEntry.getAny(false).typeName()<<"\""
660  ",value=\""<<filterValueToString(theEntry)<<"\"}"
661  "\nin the parameter (sub)list \""<<this->name()<<"\""
662  "\nexists in the list of valid parameters but has the wrong type."
663  "\n\nThe correct type is \""
664  << validEntry->getAny(false).typeName() << "\"."
665  );
666  // Note: If there is no validator for this item, then we can not
667  // validate the value of the parameter, only its type!
668  }
669  if( theEntry.isList() && depth > 0 ) {
670  sublist_list.push_back(
671  ListPlusValidList(
672  &getValue<ParameterList>(theEntry),
673  &getValue<ParameterList>(*validEntry)
674  )
675  );
676  }
677  }
678  }
679  //
680  // B) Loop through the valid parameters at this level that are not set in
681  // *this, and set their defaults.
682  //
683  {
684  ConstIterator itr;
685  for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
686  const std::string &validEntryName = validParamList.name(itr);
687  const ParameterEntry &validEntry = validParamList.entry(itr);
688  const ParameterEntry *theEntry = this->getEntryPtr(validEntryName);
689  if (!theEntry) {
690  // This entry does not exist, so add it. Here we will only set the
691  // value of the entry and its validator and and leave off the
692  // documentation. The reason that the validator is set is so that it
693  // can be used to extract and validate entries in the transformed list
694  // *this without having to refer back to the valid parameter list.
695  ParameterEntry newEntry;
696  newEntry.setAnyValue(
697  validEntry.getAny(),
698  true // isDefault
699  );
701  if (nonnull(validator=validEntry.validator())) {
702 #if defined(HAVE_TEUCHOS_MODIFY_DEFAULTS_DURING_VALIDATION)
703  validEntry.validator()->validateAndModify(this->name(itr), validEntryName, &newEntry);
704  // validateAndModify changes the default status so we reset it
705  newEntry.setAnyValue(newEntry.getAny(), true);
706 #endif
707  newEntry.setValidator(validator);
708  }
709  this->setEntry(validEntryName,newEntry);
710  }
711  }
712  }
713  //
714  // C) Loop through the sublists and validate their parameters and set their
715  // defaults!
716  //
717  for (
718  sublist_list_t::iterator sl_itr = sublist_list.begin();
719  sl_itr != sublist_list.end();
720  ++sl_itr
721  )
722  {
723  if (!sl_itr->validList->disableRecursiveValidation_) {
724  sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
725  }
726  }
727 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
728  *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
729  "for this->name()=\""<<this->name()<<"\"...\n";
730 #endif
731 }
732 
733 
734 // private
735 
736 
738 {
739  const std::string this_name = this->name();
740  Iterator itr;
741  for( itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr ) {
742  const std::string &entryName = this->name(itr);
743  const ParameterEntry &theEntry = this->entry(itr);
744  if(theEntry.isList()) {
745  ParameterList &sublistEntry = getValue<ParameterList>(theEntry);
746  sublistEntry.setName(this_name+std::string("->")+entryName);
747  if(depth > 0)
748  sublistEntry.updateSubListNames(depth-1);
749  }
750  }
751 }
752 
753 
755  const std::string & /*funcName*/, const std::string &name_in,
756  const ParameterEntry *entry_in
757  ) const
758 {
760  entry_in==NULL, Exceptions::InvalidParameterName
761  ,"Error! The parameter \""<<name_in<<"\" does not exist"\
762  "\nin the parameter (sub)list \""<<this->name()<<"\"."
763  "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
764  << this->currentParametersString()
765  );
766 }
767 
768 
770  const std::string &name_in, const ParameterEntry &entry_in
771  ) const
772 {
775  ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
776  <<entry_in.getAny(false).typeName()<<"\"!" );
777 }
778 
779 
780 void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
781  const std::string &sublist_name, const bool mustAlreadyExist) const
782 {
784  mustAlreadyExist, Exceptions::InvalidParameterName
785  ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
786  );
787 }
788 
789 
790 } // namespace Teuchos
791 
792 
793 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
794 {
795  // Check that the top-level names of the two parameter lists are the same
796  //const std::string &paramListName1 = list1.name();
797  //const std::string &paramListName2 = list2.name();
798  //if ( paramListName1 != paramListName2 ) {
799  // return false;
800  //}
801  if (!Teuchos::haveSameModifiers(list1, list2)){
802  return false;
803  }
804  ParameterList::ConstIterator itr1, itr2;
805  for(
806  itr1 = list1.begin(), itr2 = list2.begin();
807  itr1 != list1.end() && itr2 != list2.end();
808  ++itr1, ++itr2
809  )
810  {
811  const std::string &entryName1 = list1.name(itr1);
812  const std::string &entryName2 = list2.name(itr2);
813  const ParameterEntry &entry1 = list1.entry(itr1);
814  const ParameterEntry &entry2 = list2.entry(itr2);
815  if( entryName1 != entryName2 ) {
816  return false;
817  }
818  else if( entry1 != entry2 ) {
819  return false;
820  }
821  // Note that the above statement automatically recursively compares the
822  // sublists since ParameterList objects are stored in the 'any' variable
823  // held by the ParameterEntry object and this same comparison operator will
824  // be used.
825  }
826  // Check that the two parameter lists are the same length:
827  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
828  return false;
829  }
830  return true;
831 }
832 
833 
834 bool Teuchos::haveSameModifiers(const ParameterList &list1, const ParameterList &list2) {
835  // Check that the modifiers are the same
836  const RCP<const ParameterListModifier> &modifier1 = list1.getModifier();
837  const RCP<const ParameterListModifier> &modifier2 = list2.getModifier();
838  // Compare the modifiers.
839  const bool modifier1_is_null = is_null(modifier1);
840  const bool modifier2_is_null = is_null(modifier2);
841  if( modifier1_is_null || modifier2_is_null ){
842  if ( modifier1_is_null != modifier2_is_null ){
843  return false;
844  }
845  } else if ( *modifier1 != *modifier2 ){
846  return false;
847  }
848  // Now look for more sublists
849  ParameterList::ConstIterator itr1, itr2;
850  for(
851  itr1 = list1.begin(), itr2 = list2.begin();
852  itr1 != list1.end() && itr2 != list2.end();
853  ++itr1, ++itr2
854  )
855  {
856  // Check the modifiers in each sublist.
857  const ParameterEntry &entry1 = itr1->second;
858  const ParameterEntry &entry2 = itr2->second;
859  if (entry1.isList() && entry2.isList()){
860  if ( !haveSameModifiers( Teuchos::getValue<ParameterList>(entry1),
861  Teuchos::getValue<ParameterList>(entry2) ) ){
862  return false;
863  }
864  }
865  }
866  return true;
867 }
868 
869 
870 bool Teuchos::haveSameValues( const ParameterList& list1, const ParameterList& list2, bool verbose )
871 {
872  // Check that the top-level names of the two parameter lists are the same
873  //const std::string &paramListName1 = list1.name();
874  //const std::string &paramListName2 = list2.name();
875  //if ( paramListName1 != paramListName2 ) {
876  // return false;
877  //}
878  ParameterList::ConstIterator itr1, itr2;
879  for(
880  itr1 = list1.begin(), itr2 = list2.begin();
881  itr1 != list1.end() && itr2 != list2.end();
882  ++itr1, ++itr2
883  )
884  {
885  const std::string &entryName1 = list1.name(itr1);
886  const std::string &entryName2 = list2.name(itr2);
887  const ParameterEntry &entry1 = list1.entry(itr1);
888  const ParameterEntry &entry2 = list2.entry(itr2);
889  if( entryName1 != entryName2 ) {
890  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
891  return false;
892  }
893  if( entry1.isList() && entry2.isList() ) {
894  if (
896  getValue<ParameterList>(entry1),
897  getValue<ParameterList>(entry2),
898  verbose)
899  )
900  {
901  // Note: Above we cast to a non-const ParameterList even through we
902  // only need a const ParameterList. We have to do this since a
903  // non-const ParameterList is always added initially which determines
904  // the value.
905  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
906  return false;
907  }
908  }
909  else {
910  if( entry1.getAny() != entry2.getAny() ) {
911  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
912  return false;
913  }
914  }
915  }
916  // Check that the two parameter lists are the same length:
917  if ((itr1 != list1.end()) || (itr2 != list2.end())) {
918  if (verbose) std::cerr << "lists are not the same size\n";
919  return false;
920  }
921  return true;
922 }
923 
924 
925 bool Teuchos::haveSameValuesSorted( const ParameterList& list1, const ParameterList& list2, bool verbose )
926 {
927  // Check that the top-level names of the two parameter lists are the same
928  //const std::string &paramListName1 = list1.name();
929  //const std::string &paramListName2 = list2.name();
930  //if ( paramListName1 != paramListName2 ) {
931  // return false;
932  //}
933  ParameterList::ConstIterator itr1, itr2;
934  Array<std::string> arr1, arr2;
935  for(itr1 = list1.begin(); itr1 != list1.end(); ++itr1){
936  arr1.push_back(list1.name(itr1));
937  }
938  for(itr2 = list2.begin(); itr2 != list2.end(); ++itr2){
939  arr2.push_back(list2.name(itr2));
940  }
941  // Check that the two parameter lists are the same length:
942  if (arr1.size() != arr2.size()) {
943  if (verbose) std::cerr << "lists are not the same size\n";
944  return false;
945  }
946  std::sort(arr1.begin(), arr1.end());
947  std::sort(arr2.begin(), arr2.end());
948  Array<std::string>::iterator iarr1, iarr2;
949  for(
950  iarr1 = arr1.begin(), iarr2 = arr2.begin();
951  iarr1 != arr1.end() && iarr2 != arr2.end();
952  ++iarr1, ++iarr2
953  )
954  {
955  const std::string &entryName1 = *iarr1;
956  const std::string &entryName2 = *iarr2;
957  const ParameterEntry &entry1 = list1.getEntry(entryName1);
958  const ParameterEntry &entry2 = list2.getEntry(entryName2);
959  if( entryName1 != entryName2 ) {
960  if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
961  return false;
962  }
963  if( entry1.isList() && entry2.isList() ) {
964  if (
966  getValue<ParameterList>(entry1),
967  getValue<ParameterList>(entry2),
968  verbose)
969  )
970  {
971  // Note: Above we cast to a non-const ParameterList even through we
972  // only need a const ParameterList. We have to do this since a
973  // non-const ParameterList is always added initially which determines
974  // the value.
975  if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
976  return false;
977  }
978  }
979  else {
980  if( entry1.getAny() != entry2.getAny() ) {
981  if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
982  return false;
983  }
984  }
985  }
986  return true;
987 }
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.