47 #ifndef TEUCHOS_YAMLPARSER_DEF_H_ 48 #define TEUCHOS_YAMLPARSER_DEF_H_ 55 #include "Teuchos_YamlParser_decl.hpp" 76 static T eval(YAML::Node
const& node) {
78 if (node.Tag() ==
"!") {
79 throw std::runtime_error(
"quoted_as from quoted string to number");
86 struct QuotedAs<std::string> {
88 static std::string eval(YAML::Node
const& node) {
return node.as<std::string>(); }
92 static T quoted_as(YAML::Node
const& node) {
return QuotedAs<T>::eval(node); }
97 for(YAML::const_iterator it = node.begin(); it != node.end(); it++)
104 void checkYamlTwoDArray(
const YAML::Node& node,
const std::string& key)
106 for (YAML::const_iterator it = node.begin(); it != node.end(); ++it)
108 if (it->size() != node.begin()->size())
110 throw YamlSequenceError(std::string(
"TwoDArray \"") + key +
"\" has irregular sizes");
122 for (YAML::const_iterator rit = node.begin(); rit != node.end(); ++rit)
125 for (YAML::const_iterator cit = rit->begin(); cit != rit->end(); ++cit)
127 arr(i, j) = quoted_as<T>(*cit);
137 void updateParametersFromYamlFile(
const std::string& yamlFileName,
146 void updateParametersFromYamlCString(
const char*
const data,
161 void updateParametersFromYamlString(
const std::string& yamlData,
178 return YAMLParameterList::parseYamlFile(yamlFileName);
183 std::stringstream ss(yamlStr);
184 return YAMLParameterList::parseYamlStream(ss);
187 void writeParameterListToYamlOStream(
189 std::ostream &yamlOut
192 YAMLParameterList::writeYamlStream(yamlOut, paramList);
195 void writeParameterListToYamlFile(
197 const std::string &yamlFileName
200 YAMLParameterList::writeYamlFile(yamlFileName, paramList);
203 std::string convertXmlToYaml(
const std::string& xmlFileName)
208 std::string yamlFileName;
209 if(xmlFileName.find(
".xml") == std::string::npos)
211 yamlFileName = xmlFileName +
".yaml";
215 yamlFileName = xmlFileName.substr(0, xmlFileName.length() - 4) +
".yaml";
217 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
221 void convertXmlToYaml(
const std::string& xmlFileName,
const std::string& yamlFileName)
226 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
229 void convertXmlToYaml(std::istream& xmlStream, std::ostream& yamlStream)
232 std::string xmlString(std::istreambuf_iterator<char>(xmlStream), {});
236 YAMLParameterList::writeYamlStream(yamlStream, *toConvert);
242 Iter i = lhs.
begin();
243 Iter j = rhs.
begin();
248 std::cout <<
"Parameter list names: \"" << lhs.
name() <<
"\" and \"" << rhs.
name() <<
"\".\n";
252 for(; i != lhs.
end(); i++)
254 const std::string& key = lhs.
name(i);
261 std::cout <<
"One list is missing parameter: \"" << key <<
"\"\n";
273 std::cout <<
"Values for key \"" << key <<
"\" have different types: \"" <<
281 if(!haveSameValuesUnordered(Teuchos::any_cast<Teuchos::ParameterList>(any1), Teuchos::any_cast<
Teuchos::ParameterList>(any2), verbose))
294 std::cout <<
"Values for key \"" << key <<
"\" are different.\n";
306 std::cout <<
"Lists \"" << lhs.
name() <<
"\" and \"" << rhs.
name() <<
"\" have different number of parameters.\n";
313 namespace YAMLParameterList
319 std::vector<YAML::Node> baseMap = YAML::LoadAll(text);
320 return readParams(baseMap);
326 std::vector<YAML::Node> baseMap = YAML::LoadAll(text);
327 return readParams(baseMap);
332 std::vector<YAML::Node> baseMap = YAML::LoadAllFromFile(yamlFile);
333 return readParams(baseMap);
338 std::vector<YAML::Node> baseMap = YAML::LoadAll(yaml);
339 return readParams(baseMap);
347 for(
size_t i = 0; i < lists.size(); i++)
349 processMapNode(lists[i], *pl,
true);
356 if(node.Type() != YAML::NodeType::Map)
358 throw YamlStructureError(
"All top-level elements of the YAML file must be maps.");
363 processMapNode(node.begin()->second, parent);
367 for(YAML::const_iterator i = node.begin(); i != node.end(); i++)
370 if(i->first.Type() != YAML::NodeType::Scalar)
372 throw YamlKeyError(
"Keys must be plain strings");
375 const std::string key = quoted_as<std::string>(i->first);
376 processKeyValueNode(key, i->second, parent, topLevel);
381 void processKeyValueNode(
const std::string& key,
const YAML::Node& node,
Teuchos::ParameterList& parent,
bool topLevel)
385 if(node.Type() == YAML::NodeType::Scalar)
389 parent.
set(key, quoted_as<int>(node));
395 parent.
set(key, quoted_as<double>(node));
401 std::string rawString = quoted_as<std::string>(node);
402 if(rawString ==
"true")
404 parent.
set<
bool>(key,
true);
406 else if(rawString ==
"false")
408 parent.
set<
bool>(key,
false);
412 parent.
set(key, rawString);
417 throw YamlScalarError(
"YAML scalars must be int, double, bool or string.");
422 else if(node.Type() == YAML::NodeType::Map)
426 processMapNode(node, parent);
431 processMapNode(node, sublist);
434 else if(node.Type() == YAML::NodeType::Sequence)
436 if (node.begin()->Type() == YAML::NodeType::Sequence) {
437 checkYamlTwoDArray(node, key);
438 YAML::Node
const& first_value = *(node.begin()->begin());
441 quoted_as<int>(first_value);
442 parent.
set(key, getYamlTwoDArray<int>(node));
448 quoted_as<double>(first_value);
449 parent.
set(key, getYamlTwoDArray<double>(node));
455 quoted_as<std::string>(first_value);
456 parent.
set(key, getYamlTwoDArray<std::string>(node));
460 throw YamlSequenceError(std::string(
"TwoDArray \"") + key +
"\" must contain int, double, bool or string");
465 YAML::Node
const& first_value = *(node.begin());
468 quoted_as<int>(first_value);
469 parent.
set(key, getYamlArray<int>(node));
475 quoted_as<double>(first_value);
476 parent.
set(key, getYamlArray<double>(node));
482 quoted_as<std::string>(first_value);
483 parent.
set(key, getYamlArray<std::string>(node));
487 throw YamlSequenceError(std::string(
"Array \"") + key +
"\" must contain int, double, bool or string");
493 else if(node.Type() == YAML::NodeType::Null)
496 parent.
set(key, std::string());
501 throw YamlUndefinedNodeError(
"Value type in a key-value pair must be one of: int, double, string, array, sublist.");
508 auto flags = yaml.flags();
510 std::ostringstream testStream;
511 testStream.flags(flags);
513 testStream << testVal;
514 bool popFlags =
false;
515 if(testStream.str() ==
"1")
521 std::cout <<
"Warning: yaml stream format flags would confuse double with integer value with int.\n";
522 std::cout <<
"Setting std::ios::showpoint on the stream to fix this (will restore flags when done)\n";
523 auto flagsCopy = flags;
524 flagsCopy |= std::ios::showpoint;
527 yaml <<
"%YAML 1.1\n---\n";
528 yaml <<
"ANONYMOUS:";
535 writeParameterList(pl, yaml, 2);
547 std::ofstream yaml(yamlFile);
554 yaml << std::scientific << std::setprecision(17);
555 writeYamlStream(yaml, pl);
567 for(PLIter it = pl.
begin(); it != pl.
end(); it++)
569 writeParameter(pl.
name(it), pl.
entry(it), yaml, indentLevel);
574 template <
typename T>
576 static void write(T
const& x, std::ostream& stream) {
582 struct YamlWrite<double> {
583 static void write(
double const& x, std::ostream& stream) {
584 generalWriteDouble(x, stream);
589 struct YamlWrite<std::string> {
590 static void write(std::string
const& x, std::ostream& stream) {
591 generalWriteString(x, stream);
595 template <
typename T>
602 if (i) stream <<
", ";
606 if (j) stream <<
", ";
607 YamlWrite<T>::write(arr(i, j), stream);
614 void writeParameter(
const std::string& paramName,
const Teuchos::ParameterEntry& entry, std::ostream& yaml,
int indentLevel)
616 for(
int i = 0; i < indentLevel; i++)
620 generalWriteString(paramName, yaml);
624 writeParameterList(Teuchos::getValue<Teuchos::ParameterList>(entry), yaml, indentLevel + 2);
633 for(
int i = 0; i < arr.
size(); i++)
636 if(i != arr.size() - 1)
643 for(
int i = 0; i < arr.
size(); i++)
645 generalWriteDouble(arr[i], yaml);
646 if(i != arr.
size() - 1)
653 for(
int i = 0; i < arr.
size(); i++)
655 generalWriteString(arr[i], yaml);
656 if(i != arr.
size() - 1)
666 writeYamlTwoDArray<int>(
667 Teuchos::getValue<Teuchos::TwoDArray<int> >(entry), yaml);
671 writeYamlTwoDArray<double>(
672 Teuchos::getValue<Teuchos::TwoDArray<double> >(entry), yaml);
676 writeYamlTwoDArray<std::string>(
677 Teuchos::getValue<Teuchos::TwoDArray<std::string> >(entry), yaml);
680 else if(entry.
isType<
int>())
682 yaml << Teuchos::getValue<int>(entry);
684 else if(entry.
isType<
double>())
686 generalWriteDouble(Teuchos::getValue<double>(entry), yaml);
688 else if(entry.
isType<std::string>())
690 std::string& str = Teuchos::getValue<std::string>(entry);
691 if(strchr(str.c_str(),
'\n'))
699 size_t next = str.find(
'\n', index);
700 for(
int i = 0; i < indentLevel + 2; i++)
704 if(next == std::string::npos)
706 yaml << str.substr(index, std::string::npos);
711 yaml << str.substr(index, next - index) <<
'\n';
718 generalWriteString(str, yaml);
721 else if(entry.
isType<
bool>())
723 yaml << (Teuchos::getValue<bool>(entry) ?
"true" :
"false");
728 void generalWriteString(
const std::string& str, std::ostream& yaml)
730 if(stringNeedsQuotes(str))
732 yaml <<
'\'' << str <<
'\'';
740 void generalWriteDouble(
double d, std::ostream& yaml)
745 template <
typename T>
746 static bool canBeParsedAs(std::string
const& s) {
747 std::istringstream iss(s);
749 iss >> std::noskipws >> val;
750 return iss.eof() && !iss.fail();
753 static bool containsSpecialCharacters(std::string
const& s) {
754 char const*
const control_chars =
":{}[],&*#?|-<>=!%@\\";
755 return s.find_first_of(control_chars) != std::string::npos;
758 bool stringNeedsQuotes(
const std::string& s)
760 return containsSpecialCharacters(s) ||
761 canBeParsedAs<int>(s) ||
762 canBeParsedAs<double>(s);
A thin wrapper around the Teuchos Array class that allows for 2 dimensional arrays.
C++ Standard Library compatable filtered iterator.
ConstIterator begin() const
An iterator pointing to the first entry.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Set a parameter whose value has type T.
This object is held as the "value" in the Teuchos::ParameterList std::map.
const ParameterEntry & entry(ConstIterator i) const
Access to ParameterEntry (i.e., returns i->second)
Ordinal numParams() const
Get the number of stored parameters.
size_type getNumRows() const
returns the number of rows in the TwoDArray.
Modified boost::any class, which is a container for a templated value.
Simple helper functions that make it easy to read and write XML to and from a parameterlist.
ConstIterator end() const
An iterator pointing beyond the last entry.
A thin wrapper around the Array class which causes it to be interpreted as a 2D Array.
size_type getNumCols() const
returns the number of columns in the TwoDArray.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
void resizeCols(size_type numberOfCols)
Changes the number of rows in the matrix.
void resizeRows(size_type numberOfRows)
Changes the number of rows in the matrix.
bool isList() const
Return whether or not the value itself is a list.
A list of parameters of arbitrary type.
bool isTwoDArray() const
Test if the type of data being contained is a Teuchos::TwoDArray.
ParameterList & setParameters(const ParameterList &source)
bool isType() const
Test the type of the data being contained.
const std::type_info & type() const
Return the type of value being stored.
const std::string & name() const
The name of this ParameterList.
any & getAny(bool activeQry=true)
Direct access to the Teuchos::any data value underlying this object. The bool argument activeQry (def...
void push_back(const value_type &x)
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
ParameterList & setParametersNotAlreadySet(const ParameterList &source)
std::string typeName() const
Return the name of the type.
bool isParameter(const std::string &name) const
Whether the given parameter exists in this list.
bool isArray() const
Test if the type of data being contained is a Teuchos::Array.
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.
ParameterEntry & getEntry(const std::string &name)
Retrieves an entry with the name name.
Simple helper functions that make it easy to read and write Yaml to and from a parameterlist.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...