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 
43 #include "Teuchos_ParameterListModifier.hpp"
44 #include "Teuchos_ParameterList.hpp"
45 #include "Teuchos_StrUtils.hpp"
46 
47 namespace Teuchos {
48 
49 
50 // Constructors and/or destructors
ParameterListModifier(const std::string & name_in)51 ParameterListModifier::ParameterListModifier(const std::string &name_in)
52   :name_(name_in)
53 {}
54 
~ParameterListModifier()55 ParameterListModifier::~ParameterListModifier()
56 {}
57 
58 
printDoc(std::string const & docString,std::ostream & out) const59 void ParameterListModifier::printDoc(std::string const& docString, std::ostream &out) const
60 {
61   StrUtils::printLines(out,"# ",docString);
62   out << "#  Modifier Used: " << name_ << std::endl;
63 }
64 
65 
findMatchingBaseNames(const ParameterList & pl,const std::string & base_name,const bool & find_parameters,const bool & find_sublists) const66 Array<std::string> ParameterListModifier::findMatchingBaseNames(const ParameterList &pl,
67     const std::string &base_name, const bool &find_parameters, const bool &find_sublists) const
68 {
69   Array<std::string> matches(0);
70   ParameterList::ConstIterator itr;
71   for (itr = pl.begin(); itr != pl.end(); ++itr) {
72     const std::string &name = pl.name(itr);
73     std::size_t found = name.find(base_name);
74     if (found == 0){
75       if (pl.isSublist(name)){
76         if (find_sublists){
77           matches.push_back(name);
78         }
79       } else{
80         if (find_parameters){
81           matches.push_back(name);
82         }
83       }
84     }
85   }
86   return matches;
87 }
88 
89 
expandParameters(const std::string & param_template_name,ParameterList & pl,ParameterList & valid_pl,const Array<std::string> & exclude_parameters) const90 int ParameterListModifier::expandParameters(
91     const std::string &param_template_name, ParameterList &pl, ParameterList &valid_pl,
92     const Array<std::string> &exclude_parameters) const
93 {
94   int replacements = 0;
95   auto ignore_names = exclude_parameters;
96   std::sort(ignore_names.begin(), ignore_names.end());
97   ParameterList::ConstIterator itr;
98   if (valid_pl.isParameter(param_template_name)){
99     ParameterEntry &valid_pl_entry = valid_pl.getEntry(param_template_name);
100     for (itr = pl.begin(); itr != pl.end(); ++itr) {
101       const std::string &param_name = pl.name(itr);
102       if (!pl.isSublist(param_name)){
103         if (!std::binary_search(ignore_names.begin(), ignore_names.end(), param_name)){
104           valid_pl.setEntry(param_name, valid_pl_entry);
105           replacements += 1;
106         }
107       }
108     }
109     valid_pl.remove(param_template_name);
110   }
111   return replacements;
112 }
113 
114 
expandSublists(const std::string & sublist_template_name,ParameterList & pl,ParameterList & valid_pl,const Array<std::string> & exclude_sublists) const115 int ParameterListModifier::expandSublists(
116     const std::string &sublist_template_name, ParameterList &pl, ParameterList &valid_pl,
117     const Array<std::string> &exclude_sublists) const
118 {
119   int replacements = 0;
120   auto ignore_names = exclude_sublists;
121   std::sort(ignore_names.begin(), ignore_names.end());
122   ParameterList::ConstIterator itr;
123   if (valid_pl.isSublist(sublist_template_name)){
124     ParameterList &valid_pl_sublist = valid_pl.get<ParameterList>(sublist_template_name);
125     for (itr = pl.begin(); itr != pl.end(); ++itr) {
126       const std::string &subname = pl.name(itr);
127       if (pl.isSublist(subname)){
128         if (!std::binary_search(ignore_names.begin(), ignore_names.end(), subname)){
129           valid_pl.set(subname, valid_pl_sublist);
130           replacements += 1;
131         }
132       }
133     }
134     valid_pl.remove(sublist_template_name);
135   }
136   return replacements;
137 }
138 
139 
expandSublistsUsingBaseName(const std::string & base_name,ParameterList & pl,ParameterList & valid_pl,const bool & allow_base_name) const140 int ParameterListModifier::expandSublistsUsingBaseName(
141     const std::string &base_name, ParameterList &pl, ParameterList &valid_pl,
142     const bool &allow_base_name) const
143 {
144   int replacements = 0;
145   bool delete_base_name = true;
146   if (valid_pl.isSublist(base_name)){
147     if (pl.isSublist(base_name)){
148       TEUCHOS_TEST_FOR_EXCEPTION(!allow_base_name, std::logic_error,
149           "Sublist can't have the same name as the parameter template name "
150           "without `allow_base_name=true`.");
151       delete_base_name = false;
152     }
153     Array<std::string> matches = findMatchingBaseNames(pl, base_name, false, true);
154     replacements = matches.length();
155     for (const std::string &match_name : matches){
156       valid_pl.set(match_name, valid_pl.get<ParameterList>(base_name));
157     }
158     if (delete_base_name){
159       valid_pl.remove(base_name);
160     }
161   }
162   return replacements;
163 }
164 
165 
setDefaultsInSublists(const std::string & param_name,ParameterList & pl,const Array<std::string> & sublist_names,const bool remove_param) const166 int ParameterListModifier::setDefaultsInSublists(const std::string &param_name,
167     ParameterList &pl, const Array<std::string> &sublist_names,
168     const bool remove_param) const
169 {
170   int num_defaults = 0;
171   if (pl.isParameter(param_name)){
172     for (const std::string &sublist_name : sublist_names){
173       if (pl.isSublist(sublist_name)){
174         ParameterList &sublist = pl.sublist(sublist_name);
175         if (!sublist.isParameter(param_name)){
176           ParameterEntry &pl_entry = pl.getEntry(param_name);
177           sublist.setEntry(param_name, pl_entry);
178         }
179       }
180     }
181     if (remove_param){
182       pl.remove(param_name);
183     }
184   }
185   return num_defaults;
186 }
187 
188 
189 } // namespace Teuchos
190