00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "Teuchos_ParameterList.hpp"
00032
00033 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00034 #include "Teuchos_VerboseObject.hpp"
00035 #endif
00036
00037
00038
00039
00040
00041
00042
00043 namespace {
00044
00045 std::string filterValueToString(const Teuchos::ParameterEntry& entry )
00046 {
00047 return ( entry.isList() ? std::string("...") : toString(entry.getAny()) );
00048 }
00049
00050 struct ListPlusValidList {
00051 Teuchos::ParameterList *list;
00052 Teuchos::ParameterList *validList;
00053 ListPlusValidList(
00054 Teuchos::ParameterList *_list
00055 ,Teuchos::ParameterList *_validList
00056 )
00057 :list(_list),validList(_validList)
00058 {}
00059 };
00060
00061 }
00062
00063 namespace Teuchos {
00064
00065 ParameterList::ParameterList()
00066 :name_("ANONYMOUS")
00067 {}
00068
00069 ParameterList::ParameterList(const std::string &name)
00070 :name_(name)
00071 {}
00072
00073 ParameterList::ParameterList(const ParameterList& source)
00074 {
00075 name_ = source.name_;
00076 params_ = source.params_;
00077 }
00078
00079 ParameterList& ParameterList::operator=(const ParameterList& source)
00080 {
00081 if (&source == this)
00082 return *this;
00083 name_ = source.name_;
00084 params_ = source.params_;
00085 return *this;
00086 }
00087
00088 ParameterList& ParameterList::setParameters(const ParameterList& source)
00089 {
00090 for( ConstIterator i = source.begin(); i != source.end(); ++i ) {
00091 const std::string &name_i = this->name(i);
00092 const ParameterEntry &entry_i = this->entry(i);
00093 if(entry_i.isList()) {
00094 this->sublist(name_i).setParameters(getValue<ParameterList>(entry_i));
00095 }
00096 else {
00097 this->setEntry(name_i,entry_i);
00098 }
00099 }
00100 this->updateSubListNames();
00101 return *this;
00102 }
00103
00104 ParameterList::~ParameterList()
00105 {}
00106
00107 void ParameterList::unused(ostream& os) const
00108 {
00109 for (ConstIterator i = params_.begin(); i != params_.end(); ++i) {
00110 if (!(entry(i).isUsed())) {
00111 os << "WARNING: Parameter \"" << name(i) << "\" " << entry(i)
00112 << " is unused" << endl;
00113 }
00114 }
00115 }
00116
00117 std::string ParameterList::currentParametersString() const
00118 {
00119 std::ostringstream oss;
00120 oss << "{";
00121 ParameterList::ConstIterator itr;
00122 int i;
00123 for( itr = this->begin(), i = 0; itr != this->end(); ++itr, ++i ) {
00124 const std::string &entryName = this->name(itr);
00125 const ParameterEntry &entry = this->entry(itr);
00126 if(i) oss << ",";
00127 oss
00128 << "\""<<entryName<<"\":"<<entry.getAny().typeName()
00129 <<"="<<filterValueToString(entry);
00130 }
00131 oss << "}";
00132 return oss.str();
00133 }
00134
00135 bool ParameterList::isSublist(const string& name) const
00136 {
00137 ConstIterator i = params_.find(name);
00138
00139 if (i != params_.end())
00140 return (entry(i).isList());
00141
00142 return false;
00143 }
00144
00145 bool ParameterList::isParameter(const string& name) const
00146 {
00147 return (params_.find(name) != params_.end());
00148 }
00149
00150 ParameterList& ParameterList::sublist(const string& name, bool mustAlreadyExist)
00151 {
00152
00153 Iterator i = params_.find(name);
00154
00155
00156
00157 if (i != params_.end()) {
00158 TEST_FOR_EXCEPTION(
00159 !entry(i).isList(), std::runtime_error,
00160 " Parameter " << name << " is not a list, it is of type \""
00161 <<entry(i).getAny(false).typeName()<<"\"!" );
00162 return getValue<ParameterList>(entry(i));
00163 }
00164
00165
00166 TEST_FOR_EXCEPTION(
00167 mustAlreadyExist, Exceptions::InvalidParameter
00168 ,"The sublist "<<this->name()<<"->\""<<name<<"\" does not exist!"
00169 );
00170 const ParameterList newSubList(this->name()+std::string("->")+name);
00171 return any_cast<ParameterList>(
00172 params_.insert(
00173 Map::value_type(name,ParameterEntry(newSubList,false,true))
00174 ).first->second.getAny(false)
00175 );
00176
00177
00178
00179 }
00180
00181 const ParameterList& ParameterList::sublist(const string& name) const
00182 {
00183
00184 ConstIterator i = params_.find(name);
00185
00186
00187 TEST_FOR_EXCEPTION(
00188 i == params_.end(), Exceptions::InvalidParameter
00189 ,"The sublist "<<this->name()<<"->\""<<name<<"\" does not exist!"
00190 );
00191
00192
00193 TEST_FOR_EXCEPTION( !entry(i).isList(), std::runtime_error,
00194 " Parameter " << name << " is not a list!" );
00195 return getValue<ParameterList>(entry(i));
00196 }
00197
00198 ostream& ParameterList::print(ostream& os, int indent, bool showTypes, bool showFlags) const
00199 {
00200 if (params_.begin() == params_.end()) {
00201 for (int j = 0; j < indent; j ++)
00202 os << ' ';
00203 os << "[empty list]" << endl;
00204 }
00205 else {
00206
00207 for (ConstIterator i = params_.begin(); i != params_.end(); ++i)
00208 {
00209 const ParameterEntry &entry_i = entry(i);
00210 if(entry_i.isList())
00211 continue;
00212 for (int j = 0; j < indent; j ++)
00213 os << ' ';
00214 os << name(i);
00215 if(showTypes)
00216 os << " : " << entry_i.getAny(false).typeName();
00217 os << " = "; entry_i.leftshift(os,showFlags); os << endl;
00218 }
00219
00220 for (ConstIterator i = params_.begin(); i != params_.end(); ++i)
00221 {
00222 const ParameterEntry &entry_i = entry(i);
00223 if(!entry_i.isList())
00224 continue;
00225 for (int j = 0; j < indent; j ++)
00226 os << ' ';
00227 os << name(i) << " -> " << endl;
00228 getValue<ParameterList>(entry_i).print(os, indent + 2,showTypes,showFlags);
00229 }
00230 }
00231 return os;
00232 }
00233
00234 ParameterList::ConstIterator ParameterList::begin() const
00235 {
00236 return params_.begin();
00237 }
00238
00239 ParameterList::ConstIterator ParameterList::end() const
00240 {
00241 return params_.end();
00242 }
00243
00244
00245
00246 #if defined(TFLOP)
00247
00248 const string& ParameterList::name(ConstIterator i) const
00249 {
00250 return ((*i).first);
00251 }
00252
00253 ParameterEntry& ParameterList::entry(Iterator i)
00254 {
00255 return ((*i).second);
00256 }
00257
00258 const ParameterEntry& ParameterList::entry(ConstIterator i) const
00259 {
00260 return ((*i).second);
00261 }
00262
00263 #else
00264
00265 const string& ParameterList::name(ConstIterator i) const
00266 {
00267 return (i->first);
00268 }
00269
00270 ParameterEntry& ParameterList::entry(Iterator i)
00271 {
00272 return (i->second);
00273 }
00274
00275 const ParameterEntry& ParameterList::entry(ConstIterator i) const
00276 {
00277 return (i->second);
00278 }
00279
00280 #endif
00281
00282 void ParameterList::validateParameters(
00283 const ParameterList &validParamList
00284 ,const int depth
00285 ,const EValidateUsed validateUsed
00286 ,const EValidateDefaults validateDefaults
00287 ) const
00288 {
00289 typedef std::deque<ListPlusValidList> sublist_list_t;
00290 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00291 RefCountPtr<FancyOStream> out = VerboseObjectBase::getDefaultOStream();
00292 OSTab tab(out);
00293 *out << "\n*** Entering ParameterList::validateParameters(...) for this->name()=\""<<this->name()<<"\"...\n";
00294 #endif
00295
00296
00297
00298
00299
00300 sublist_list_t sublist_list;
00301 ConstIterator itr;
00302 for( itr = this->begin(); itr != this->end(); ++itr ) {
00303 const std::string &entryName = this->name(itr);
00304 const ParameterEntry &entry = this->entry(itr);
00305 if(
00306 ( entry.isUsed() && validateUsed!=VALIDATE_USED_ENABLED )
00307 ||
00308 ( entry.isDefault() && validateDefaults!=VALIDATE_DEFAULTS_ENABLED )
00309 )
00310 {
00311 continue;
00312 }
00313 const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
00314 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00315 OSTab tab(out);
00316 *out << "\nentryName=\""<<entryName<<"\"\n";
00317 #endif
00318 const bool validType = ( validEntry!=NULL ? entry.getAny(false).type() == validEntry->getAny(false).type() : false );
00319 TEST_FOR_EXCEPTION(
00320 !( validEntry!=NULL && validType )
00321 ,Exceptions::InvalidParameter
00322 ,"Error, the parameter {name=\""<<entryName<<"\",type=\""<<entry.getAny(false).typeName()<<"\""
00323 ",value=\""<<filterValueToString(entry)<<"\"} in the parameter (sub)list \""<<this->name()<<"\" "
00324 << ( validEntry==NULL
00325 ? "was not found in the list of valid parameters"
00326 : std::string("exists in the list of valid parameters but has the wrong type. The correct type is \"")
00327 +validEntry->getAny(false).typeName()+std::string("\"")
00328 )
00329 << ". The valid parameters and types are "<<validParamList.currentParametersString()
00330 );
00331 if( entry.isList() && depth > 0 ) {
00332 sublist_list.push_back(
00333 ListPlusValidList(
00334 &getValue<ParameterList>(entry),&getValue<ParameterList>(*validEntry)
00335 )
00336 );
00337 }
00338 }
00339
00340
00341
00342 for( sublist_list_t::const_iterator sl_itr = sublist_list.begin(); sl_itr != sublist_list.end(); ++sl_itr ) {
00343 sl_itr->list->validateParameters(
00344 *sl_itr->validList
00345 ,depth-1
00346 ,validateUsed
00347 ,validateDefaults
00348 );
00349 }
00350 #ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
00351 *out << "\n*** Existing ParameterList::validateParameters(...) for this->name()=\""<<this->name()<<"\"...\n";
00352 #endif
00353 }
00354
00355
00356
00357 void ParameterList::updateSubListNames(int depth)
00358 {
00359 const std::string this_name = this->name();
00360 Map::iterator itr;
00361 for( itr = params_.begin(); itr != params_.end(); ++itr ) {
00362 const std::string &entryName = this->name(itr);
00363 const ParameterEntry &entry = this->entry(itr);
00364 if(entry.isList()) {
00365 ParameterList &sublist = getValue<ParameterList>(entry);
00366 sublist.setName(this_name+std::string("->")+entryName);
00367 if(depth > 0)
00368 sublist.updateSubListNames(depth-1);
00369 }
00370 }
00371 }
00372
00373 }
00374
00375 bool Teuchos::operator==( const ParameterList& list1, const ParameterList& list2 )
00376 {
00377 bool isSame = true;
00378 ParameterList::ConstIterator itr1, itr2;
00379 for(
00380 itr1 = list1.begin(), itr2 = list2.begin();
00381 itr1 != list1.end() && itr2 != list2.end();
00382 ++itr1, ++itr2
00383 )
00384 {
00385 const std::string &entryName1 = list1.name(itr1);
00386 const std::string &entryName2 = list2.name(itr2);
00387 const ParameterEntry &entry1 = list1.entry(itr1);
00388 const ParameterEntry &entry2 = list2.entry(itr2);
00389 if( entryName1 != entryName2 )
00390 isSame = false;
00391 else if( entry1 != entry2 )
00392 isSame = false;
00393
00394
00395
00396
00397 }
00398 return isSame;
00399 }