Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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>
47#include "Teuchos_StrUtils.hpp"
49
50
51namespace {
52
53
54std::string filterValueToString(const Teuchos::ParameterEntry& entry )
55{
56 return ( entry.isList() ? std::string("...") : toString(entry.getAny()) );
57}
58
59
60struct 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
75namespace Teuchos {
76
77
78// Constructors/Destructor/Info
79
80
81ParameterList::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
202void 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
231bool 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
242bool 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 =
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);
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
324const 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
346std::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
405std::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"
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{
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
767void 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
780bool 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
821bool 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
848bool 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 (
873 !haveSameValues(
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
903bool 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 (
943 !haveSameValuesSorted(
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}
Templated Parameter List class.
A std::string utilities class for Teuchos.
C++ Standard Library compatable filtered iterator.
This object is held as the "value" in the Teuchos::ParameterList std::map.
void setValidator(RCP< const ParameterEntryValidator > const &validator)
Set the validator.
bool isUsed() const
Return whether or not the value has been used; i.e., whether or not the value has been retrieved via ...
any & getAny(bool activeQry=true)
Direct access to the Teuchos::any data value underlying this object. The bool argument activeQry (def...
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 docString() const
Return the (optional) documentation std::string.
bool isList() const
Return whether or not the value itself is a list.
void setAnyValue(const any &value, bool isDefault=false)
Set the value as an any object.
bool isDefault() const
Indicate whether this entry takes on the default value.
Utility class for setting and passing in print options.
PrintOptions & showFlags(bool _showFlags)
PrintOptions & showTypes(bool _showTypes)
PrintOptions & showDefault(bool _showDefault)
A list of parameters of arbitrary type.
void reconcileParameterList(ParameterList &validParamList, const bool left_to_right=true)
Reconcile a parameter list after validation.
ParameterList & setParameters(const ParameterList &source)
const ParameterEntry & entry(ConstIterator i) const
Access to ParameterEntry (i.e., returns i->second)
RCP< const ParameterListModifier > modifier_
ConstIterator end() const
An iterator pointing beyond the last entry.
virtual ~ParameterList()
Destructor.
Ordinal numParams() const
Get the number of stored parameters.
ParameterEntry & nonconstEntry(Iterator i)
Access to ParameterEntry (i.e., returns i->second)
void validateEntryIsList(const std::string &name, const ParameterEntry &entry) const
Validate a sublist param is indeed a sublist.
ParameterList & setParametersNotAlreadySet(const ParameterList &source)
params_t params_
Parameter list.
RCP< const ParameterListModifier > getModifier() const
Return the optional modifier object.
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.
void unused(std::ostream &os) const
Print out unused parameters in the ParameterList.
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...
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,...
bool disableRecursiveModification_
Modify into list or not.
Iterator nonconstEnd()
An iterator pointing beyond the last entry.
void print() const
Print function to use in debugging in a debugger.
const std::string & name() const
The name of this ParameterList.
ParameterList()=default
Constructor.
void modifyParameterList(ParameterList &validParamList, int const depth=1000)
Modify the valid parameter list prior to validation.
bool isSublist(const std::string &name) const
Whether the given sublist exists in this list.
params_t::Iterator Iterator
Parameter container iterator typedef.
ParameterList & disableRecursiveValidation()
ParameterList & disableRecursiveReconciliation()
bool disableRecursiveValidation_
Validate into list or not.
ParameterList & operator=(const ParameterList &source)
Replace the current parameter list with source.
ParameterEntry * getEntryPtr(const std::string &name)
Retrieves the pointer for an entry with the name name if it exists.
params_t::ConstIterator ConstIterator
Parameter container const iterator typedef.
std::string name_
Name of the (sub)list.
ConstIterator begin() const
An iterator pointing to the first entry.
ParameterList & disableRecursiveModification()
void validateEntryExists(const std::string &funcName, const std::string &name, const ParameterEntry *entry) const
Validate that a parameter exists.
void validateMissingSublistMustExist(const std::string &baselist_name, const std::string &sublist_name, const bool mustAlreadyExist) const
Throw a sublist does not exist exception.
bool disableRecursiveReconciliation_
Reconcile into list or not.
std::string currentParametersString() const
Create a single formated std::string of all of the zero-level parameters in this list.
ParameterList & setEntry(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
bool isParameter(const std::string &name) const
Whether the given parameter exists in this list.
ParameterList & setName(const std::string &name)
Set the name of *this list.
ParameterList & disableRecursiveAll()
bool remove(std::string const &name, bool throwIfNotExists=true)
Remove a parameter (does not depend on the type of the parameter).
void updateSubListNames(int depth=0)
Update sublist names recursively.
Iterator nonconstBegin()
An iterator pointing to the first entry.
void setModifier(RCP< const ParameterListModifier > const &modifier)
EValidateDefaults
Validation defaults enum.
EValidateUsed
Validation used enum.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
Smart reference counting pointer class for automatic garbage collection.
T * get() const
Get the raw C++ pointer to the underlying object.
static std::ostream & printLines(std::ostream &os, const std::string &linePrefix, const std::string &lines)
Print lines with prefix first.
Ordinal getObjOrdinalIndex(const std::string &key) const
Get the ordinal index given the string key.
void removeObj(const Ordinal &idx)
Remove an object given its ordinal index.
Ptr< ObjType > getNonconstObjPtr(const Ordinal &idx)
Get a nonconst semi-persisting association with the stored object indexed by ordinal.
Ordinal setObj(const std::string &key, const ObjType &obj)
Set (or reset) object by value and return its ordinal index.
Ptr< const ObjType > getObjPtr(const Ordinal &idx) const
Get a const semi-persisting association with the stored object indexed by ordinal.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
std::string typeName() const
Return the name of the type.
const std::type_info & type() const
Return the type of value being stored.
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object.
#define TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
basic_OSTab< char > OSTab
std::string toString(const HashSet< Key > &h)
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)