Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_ParameterList.cpp
1// @HEADER
2// ***********************************************************************
3//
4// Teuchos: Common Tools Package
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40// @HEADER
41
42//#define TEUCHOS_PARAMETER_LIST_SHOW_TRACE
43#include <deque>
44#include <functional>
46#include "Teuchos_FancyOStream.hpp"
47#include "Teuchos_StrUtils.hpp"
48#include "Teuchos_VerboseObject.hpp"
49
50
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
85
86
88{
89 name_ = source.name_;
90 params_ = source.params_;
91 disableRecursiveValidation_ = source.disableRecursiveValidation_;
92 disableRecursiveModification_= source.disableRecursiveModification_;
93 disableRecursiveReconciliation_ = source.disableRecursiveReconciliation_;
94 modifier_ = source.modifier_;
95}
96
97
100
101
103{
104 return params_.numObjects();
105}
106
107
109{
110 if (&source == this)
111 return *this;
112 name_ = source.name_;
113 params_ = source.params_;
114 disableRecursiveValidation_ = source.disableRecursiveValidation_;
115 disableRecursiveModification_= source.disableRecursiveModification_;
116 disableRecursiveReconciliation_ = source.disableRecursiveReconciliation_;
117 modifier_ = source.modifier_;
118 return *this;
119}
120
121
122void ParameterList::setModifier(
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(
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(
157 }
158 else {
159 const ParameterEntry
160 *thisEntryPtr = this->getEntryPtr(name_i);
161 // If the entry does not already exist, then set it. Otherwise, leave the
162 // existing intery allow
163 if(!thisEntryPtr)
164 this->setEntry(name_i,entry_i);
165 }
166 }
167 this->updateSubListNames();
168 return *this;
169}
170
171
173{
174 disableRecursiveValidation_ = true;
175 return *this;
176}
177
178
180{
181 disableRecursiveModification_ = true;
182 return *this;
183}
184
185
187{
188 disableRecursiveReconciliation_ = true;
189 return *this;
190}
191
192
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
282
283 if (param_idx != SIOVOCB::getInvalidOrdinal()) {
284 // Sublist parameter exists
286 validateEntryIsList(name_in, *sublist_entry_ptr);
287 }
288 else {
289 // Sublist does not exist so we need to create a new one
290 validateMissingSublistMustExist(this->name(), name_in, mustAlreadyExist);
291 const Ordinal new_param_idx =
292 params_.setObj(
293 name_in,
295 ParameterList(this->name()+std::string("->")+name_in),
296 false,
297 true,
298 docString
299 )
300 );
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
334 validateEntryIsList(name_in, *sublist_entry_ptr);
335
336 return any_cast<ParameterList>(sublist_entry_ptr->getAny(false));
337}
338
339
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
413 int const depth,
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;
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(
441 ||
443 )
444 {
445 continue;
446 }
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 =
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(
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
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 }
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){
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();
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;
566 if (!valid_cur_node_sublist.disableRecursiveReconciliation_){
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){
579 tmp.push_back(cur_node.sublist(entry_name));
580 } else{
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
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
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 =
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(
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 {
680 for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
681 const std::string &validEntryName = validParamList.name(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.
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
724void ParameterList::updateSubListNames(int depth)
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()) {
733 sublistEntry.setName(this_name+std::string("->")+entryName);
734 if(depth > 0)
735 sublistEntry.updateSubListNames(depth-1);
736 }
737 }
738}
739
740
741void ParameterList::validateEntryExists(
742 const std::string & /*funcName*/, const std::string &name_in,
743 const ParameterEntry *entry_in
744 ) const
745{
747 entry_in==NULL, Exceptions::InvalidParameterName
748 ,"Error! The parameter \""<<name_in<<"\" does not exist"\
749 "\nin the parameter (sub)list \""<<this->name()<<"\"."
750 "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
751 << this->currentParametersString()
752 );
753}
754
755
756void ParameterList::validateEntryIsList(
757 const std::string &name_in, const ParameterEntry &entry_in
758 ) const
759{
761 !entry_in.isList(), Exceptions::InvalidParameterType
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),
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.
This object is held as the "value" in the Teuchos::ParameterList std::map.
any & getAny(bool activeQry=true)
Direct access to the Teuchos::any data value underlying this object. The bool argument activeQry (def...
bool isList() const
Return whether or not the value itself is a list.
Utility class for setting and passing in print options.
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)
ConstIterator end() const
An iterator pointing beyond the last entry.
virtual ~ParameterList()
Destructor.
Ordinal numParams() const
Get the number of stored parameters.
ParameterList & setParametersNotAlreadySet(const ParameterList &source)
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,...
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.
ParameterList & disableRecursiveValidation()
ParameterList & disableRecursiveReconciliation()
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.
ConstIterator begin() const
An iterator pointing to the first entry.
ParameterList & disableRecursiveModification()
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 & disableRecursiveAll()
bool remove(std::string const &name, bool throwIfNotExists=true)
Remove a parameter (does not depend on the type of the parameter).
EValidateDefaults
Validation defaults enum.
EValidateUsed
Validation used enum.
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.
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.
basic_OSTab< char > OSTab
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.