24#ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
25#include "yaml-cpp/yaml.h"
32#ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
47 static T eval(::YAML::Node
const& node) {
49 if (node.Tag() ==
"!") {
50 throw std::runtime_error(
"quoted_as from quoted string to number");
57struct QuotedAs<std::string> {
59 static std::string eval(::YAML::Node
const& node) {
return node.as<std::string>(); }
63static T quoted_as(::YAML::Node
const& node) {
return QuotedAs<T>::eval(node); }
69 for(::YAML::const_iterator it = node.begin(); it != node.end(); it++)
71 arr.push_back(quoted_as<T>(*it));
76bool checkYamlTwoDArrayIsRagged(const ::YAML::Node& node)
79 for (::YAML::const_iterator it = node.begin(); it != node.end(); ++it)
81 if (it->size() != node.begin()->size())
93 arr.resizeRows(node.size());
94 arr.resizeCols(node.begin()->size());
96 for (::YAML::const_iterator rit = node.begin(); rit != node.end(); ++rit)
99 for (::YAML::const_iterator cit = rit->begin(); cit != rit->end(); ++cit)
101 arr(i, j) = quoted_as<T>(*cit);
109int getYamlArrayDim(const ::YAML::Node& node)
112 if (node.Type() == ::YAML::NodeType::Sequence)
115 if (node.begin()->Type() == ::YAML::NodeType::Sequence)
118 if (node.begin()->begin()->Type() == ::YAML::NodeType::Sequence)
127template <
typename tarray_t,
typename T>
128tarray_t getYaml2DRaggedArray(::YAML::Node node,
int ndim, std::string key)
133 for (::YAML::const_iterator it1 = node.begin(); it1 != node.end(); ++it1) {
134 for (::YAML::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
135 sub_arr.push_back(quoted_as<T>(*it2));
136 } base_arr.push_back(sub_arr);
142 throw YamlSequenceError(std::string(
"MDArray \"" + key +
"\" must have dim 2."));
150template <
typename tarray_t,
typename T>
151tarray_t getYaml3DArray(::YAML::Node node,
int ndim, std::string key)
157 for (::YAML::const_iterator it1 = node.begin(); it1 != node.end(); ++it1) {
158 for (::YAML::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
159 for (::YAML::const_iterator it3 = it2->begin(); it3 != it2->end(); ++it3) {
160 sub_sub_arr.push_back(quoted_as<T>(*it3));
161 } sub_arr.push_back(sub_sub_arr);
163 } base_arr.push_back(sub_arr);
169 throw YamlSequenceError(std::string(
"MDArray \"" + key +
"\" must have dim 3."));
175void safe_set_entry(ParameterList& list, std::string
const& name_in, T
const& entry_in) {
177 "Parameter \"" << name_in <<
"\" already exists in list \"" << list.name() <<
"\"\n");
178 list.set(name_in, entry_in);
182std::string remove_trailing_whitespace(std::string
const& in) {
183 std::size_t new_end = 0;
184 for (std::size_t ri = 0; ri < in.size(); ++ri) {
185 std::size_t i = in.size() - 1 - ri;
186 if (in[i] !=
' ' && in[i] !=
'\t') {
191 return in.substr(0, new_end);
194std::string remove_trailing_whitespace_and_newlines(std::string
const& in) {
195 std::size_t new_end = 0;
196 for (std::size_t ri = 0; ri < in.size(); ++ri) {
197 std::size_t i = in.size() - 1 - ri;
198 if (in[i] !=
' ' && in[i] !=
'\t' && in[i] !=
'\n' && in[i] !=
'\r') {
203 return in.substr(0, new_end);
207bool is_parseable_as(std::string
const& text) {
208 std::istringstream ss(text);
210 ss >> std::noskipws >> val;
211 return ss.eof() && !ss.fail();
215bool is_parseable_as<int>(std::string
const& text) {
216 std::istringstream ss(text);
217 using LL =
long long;
219 ss >> std::noskipws >> val;
220 return ss.eof() && !ss.fail() &&
221 (val >= LL(std::numeric_limits<int>::min())) &&
222 (val <= LL(std::numeric_limits<int>::max()));
226T parse_as(std::string
const& text) {
227 std::istringstream ss(text);
234static char my_tolower(
char ch)
236 return std::tolower(
static_cast<unsigned char>(ch));
240static bool my_isdigit(
char ch)
242 return std::isdigit(
static_cast<unsigned char>(ch));
246bool is_parseable_as<bool>(std::string
const& text) {
248 for (std::size_t i = 0; i < text.size(); ++i) {
249 lower.push_back(my_tolower(text[i]));
251 return lower ==
"true" || lower ==
"yes" ||
252 lower ==
"false" || lower ==
"no";
256bool parse_as<bool>(std::string
const& text) {
258 for (std::size_t i = 0; i < text.size(); ++i) {
259 lower.push_back(my_tolower(text[i]));
261 return !(lower ==
"false" || lower ==
"no");
266 ParameterEntry value;
287 int infer_type()
const {
288 if (tag_type != -1) {
294 if (is_parseable_as<bool>(text)) {
297 if (is_parseable_as<int>(text)) {
300 if (is_parseable_as<long long>(text)) {
303 if (is_parseable_as<double>(text)) {
310bool operator==(Scalar
const&, Scalar
const&) {
return false; }
311std::ostream& operator<<(std::ostream& os, Scalar
const&) {
return os; }
313void safe_set_entry(ParameterList& list, std::string
const& name_in, ParameterEntry
const& entry_in) {
315 "Parameter \"" << name_in <<
"\" already exists in list \"" << list.name() <<
"\"\n");
316 list.setEntry(name_in, entry_in);
319namespace YAMLParameterList {
330 virtual void at_shift(any& result_any,
int token, std::string& text) {
333 case Teuchos::YAML::TOK_NEWLINE: {
334 std::string& result = make_any_ref<std::string>(result_any);
338 case Teuchos::YAML::TOK_SPACE:
339 case Teuchos::YAML::TOK_OTHER: {
340 result_any = text.at(0);
345 virtual void at_reduce(any& result_any,
int prod, std::vector<any>& rhs) {
348 case Teuchos::YAML::PROD_DOC:
349 case Teuchos::YAML::PROD_DOC2: {
350 std::size_t offset = prod == Teuchos::YAML::PROD_DOC2 ? 1 : 0;
352 swap(result_any, rhs.at(offset));
356 case Teuchos::YAML::PROD_TOP_BMAP: {
359 PLPair& pair = any_ref_cast<PLPair>(rhs.at(0));
360 any& pair_rhs_any = pair.value.getAny(
false);
361 result_any = pair_rhs_any;
364 case Teuchos::YAML::PROD_TOP_FIRST: {
365 if (rhs.at(0).type() ==
typeid(ParameterList)) {
366 swap(result_any, rhs.at(0));
370 case Teuchos::YAML::PROD_TOP_NEXT: {
371 if (rhs.at(1).type() ==
typeid(ParameterList)) {
373 "Can't specify multiple top-level ParameterLists in one YAML file!\n");
374 swap(result_any, rhs.at(1));
376 swap(result_any, rhs.at(0));
380 case Teuchos::YAML::PROD_BMAP_FIRST:
381 case Teuchos::YAML::PROD_FMAP_FIRST: {
383 map_first_item(result_any, rhs.at(0));
387 case Teuchos::YAML::PROD_BMAP_NEXT: {
388 map_next_item(result_any, rhs.at(0), rhs.at(1));
391 case Teuchos::YAML::PROD_FMAP_NEXT: {
392 map_next_item(result_any, rhs.at(0), rhs.at(3));
395 case Teuchos::YAML::PROD_BMAP_SCALAR:
396 case Teuchos::YAML::PROD_FMAP_SCALAR:
397 case Teuchos::YAML::PROD_FMAP_FMAP:
398 case Teuchos::YAML::PROD_FMAP_FSEQ: {
399 int scalar_type = interpret_tag(rhs.at(3));
400 map_item(result_any, rhs.at(0), rhs.at(4), scalar_type);
403 case Teuchos::YAML::PROD_BMAP_BSCALAR: {
404 map_item(result_any, rhs.at(0), rhs.at(3), Scalar::STRING);
407 case Teuchos::YAML::PROD_BMAP_BVALUE: {
408 map_item(result_any, rhs.at(0), rhs.at(4));
411 case Teuchos::YAML::PROD_BVALUE_EMPTY: {
412 result_any = ParameterList();
415 case Teuchos::YAML::PROD_BVALUE_BMAP:
416 case Teuchos::YAML::PROD_BVALUE_BSEQ: {
417 swap(result_any, rhs.at(1));
420 case Teuchos::YAML::PROD_BMAP_FMAP: {
421 map_item(result_any, rhs.at(0), rhs.at(4));
424 case Teuchos::YAML::PROD_BMAP_FSEQ: {
426 rhs.at(4).type() ==
typeid(Array<Array<Scalar>>));
427 int scalar_type = interpret_tag(rhs.at(3));
428 map_item(result_any, rhs.at(0), rhs.at(4), scalar_type);
431 case Teuchos::YAML::PROD_BSEQ_FIRST: {
432 seq_first_item(result_any, rhs.at(0));
435 case Teuchos::YAML::PROD_BSEQ_NEXT: {
436 seq_next_item(result_any, rhs.at(0), rhs.at(1));
439 case Teuchos::YAML::PROD_BSEQ_SCALAR: {
440 swap(result_any, rhs.at(3));
441 Scalar& scalar = any_ref_cast<Scalar>(result_any);
442 scalar.tag_type = interpret_tag(rhs.at(2));
445 case Teuchos::YAML::PROD_BSEQ_BSCALAR: {
446 swap(result_any, rhs.at(2));
449 case Teuchos::YAML::PROD_BSEQ_BMAP:
450 case Teuchos::YAML::PROD_BSEQ_BMAP_TRAIL:
451 case Teuchos::YAML::PROD_BSEQ_FMAP: {
452 throw ParserFail(
"Can't interpret a map inside a sequence as a Teuchos Parameter");
454 case Teuchos::YAML::PROD_BSEQ_BSEQ: {
455 swap(result_any, rhs.at(3));
458 case Teuchos::YAML::PROD_BSEQ_BSEQ_TRAIL: {
459 swap(result_any, rhs.at(4));
462 case Teuchos::YAML::PROD_BSEQ_FSEQ: {
463 swap(result_any, rhs.at(3));
466 case Teuchos::YAML::PROD_FMAP: {
467 swap(result_any, rhs.at(2));
470 case Teuchos::YAML::PROD_FMAP_EMPTY: {
471 result_any = ParameterList();
474 case Teuchos::YAML::PROD_FSEQ: {
475 swap(result_any, rhs.at(2));
477 result_any.type() ==
typeid(Array<Array<Scalar>>));
480 case Teuchos::YAML::PROD_FSEQ_EMPTY: {
481 result_any = Array<Scalar>();
484 case Teuchos::YAML::PROD_FSEQ_FIRST: {
485 seq_first_item(result_any, rhs.at(0));
488 case Teuchos::YAML::PROD_FSEQ_NEXT: {
489 seq_next_item(result_any, rhs.at(0), rhs.at(3));
492 case Teuchos::YAML::PROD_FSEQ_SCALAR: {
493 swap(result_any, rhs.at(1));
494 Scalar& scalar = any_ref_cast<Scalar>(result_any);
495 scalar.tag_type = interpret_tag(rhs.at(0));
498 case Teuchos::YAML::PROD_FSEQ_FSEQ:
499 case Teuchos::YAML::PROD_FSEQ_FMAP: {
500 swap(result_any, rhs.at(1));
503 case Teuchos::YAML::PROD_SCALAR_QUOTED:
504 case Teuchos::YAML::PROD_MAP_SCALAR_QUOTED: {
505 swap(result_any, rhs.at(0));
508 case Teuchos::YAML::PROD_SCALAR_RAW:
509 case Teuchos::YAML::PROD_MAP_SCALAR_RAW: {
510 Scalar& scalar = make_any_ref<Scalar>(result_any);
512 scalar.text = any_ref_cast<std::string>(rhs.at(0));
513 scalar.text += any_ref_cast<std::string>(rhs.at(1));
514 if (prod == Teuchos::YAML::PROD_MAP_SCALAR_RAW) {
515 scalar.text += any_ref_cast<std::string>(rhs.at(2));
517 scalar.text = remove_trailing_whitespace(scalar.text);
518 scalar.source = Scalar::RAW;
519 scalar.tag_type = -1;
522 case Teuchos::YAML::PROD_SCALAR_HEAD_OTHER:
523 case Teuchos::YAML::PROD_SCALAR_HEAD_DOT:
524 case Teuchos::YAML::PROD_SCALAR_HEAD_DASH:
525 case Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT: {
527 if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_OTHER) offset = 0;
528 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT) offset = 2;
530 char second = any_cast<char>(rhs.at(offset));
531 std::string& result = make_any_ref<std::string>(result_any);
532 if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT) result +=
'.';
533 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DASH) result +=
'-';
534 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT) result +=
"..";
538 case Teuchos::YAML::PROD_SCALAR_DQUOTED:
539 case Teuchos::YAML::PROD_SCALAR_SQUOTED: {
540 std::string& first = any_ref_cast<std::string>(rhs.at(1));
541 std::string& rest = any_ref_cast<std::string>(rhs.at(2));
542 Scalar& scalar = make_any_ref<Scalar>(result_any);
543 scalar.text += first;
545 if (prod == Teuchos::YAML::PROD_SCALAR_DQUOTED) {
546 scalar.source = Scalar::DQUOTED;
547 }
else if (prod == Teuchos::YAML::PROD_SCALAR_SQUOTED) {
548 scalar.source = Scalar::SQUOTED;
550 scalar.tag_type = -1;
553 case Teuchos::YAML::PROD_MAP_SCALAR_ESCAPED_EMPTY: {
554 result_any = std::string();
557 case Teuchos::YAML::PROD_MAP_SCALAR_ESCAPED_NEXT: {
558 swap(result_any, rhs.at(0));
559 std::string& str = any_ref_cast<std::string>(result_any);
561 str += any_ref_cast<std::string>(rhs.at(2));
564 case Teuchos::YAML::PROD_TAG: {
565 swap(result_any, rhs.at(2));
568 case Teuchos::YAML::PROD_BSCALAR: {
569 std::size_t parent_indent_level =
570 this->symbol_indentation_stack.at(
571 this->symbol_indentation_stack.size() - 5);
572 std::string& header = any_ref_cast<std::string>(rhs.at(0));
573 std::string& leading_empties_or_comments =
574 any_ref_cast<std::string>(rhs.at(2));
575 std::string& rest = any_ref_cast<std::string>(rhs.at(4));
576 std::string& content = make_any_ref<std::string>(result_any);
580 header, leading_empties_or_comments, rest,
584 case Teuchos::YAML::PROD_BSCALAR_FIRST: {
585 swap(result_any, rhs.at(0));
589 case Teuchos::YAML::PROD_BSCALAR_NEXT:
590 case Teuchos::YAML::PROD_BSCALAR_LINE:
591 case Teuchos::YAML::PROD_DESCAPE_NEXT:
592 case Teuchos::YAML::PROD_SESCAPE_NEXT: {
593 swap(result_any, rhs.at(0));
594 std::string& str = any_ref_cast<std::string>(result_any);
595 str += any_ref_cast<std::string>(rhs.at(1));
598 case Teuchos::YAML::PROD_BSCALAR_INDENT: {
599 swap(result_any, rhs.at(1));
602 case Teuchos::YAML::PROD_BSCALAR_HEADER_LITERAL:
603 case Teuchos::YAML::PROD_BSCALAR_HEADER_FOLDED: {
604 std::string& result = make_any_ref<std::string>(result_any);
605 if (prod == Teuchos::YAML::PROD_BSCALAR_HEADER_LITERAL) {
610 std::string& rest = any_ref_cast<std::string>(rhs.at(1));
614 case Teuchos::YAML::PROD_DESCAPE: {
615 std::string& str = make_any_ref<std::string>(result_any);
616 std::string& rest = any_ref_cast<std::string>(rhs.at(2));
617 str += any_cast<char>(rhs.at(1));
621 case Teuchos::YAML::PROD_SESCAPE: {
622 std::string& str = make_any_ref<std::string>(result_any);
623 std::string& rest = any_ref_cast<std::string>(rhs.at(2));
628 case Teuchos::YAML::PROD_OTHER_FIRST:
629 case Teuchos::YAML::PROD_SPACE_PLUS_FIRST: {
630 std::string& str = make_any_ref<std::string>(result_any);
631 str.push_back(any_cast<char>(rhs.at(0)));
634 case Teuchos::YAML::PROD_SCALAR_TAIL_SPACE:
635 case Teuchos::YAML::PROD_SCALAR_TAIL_OTHER:
636 case Teuchos::YAML::PROD_DESCAPED_DQUOTED:
637 case Teuchos::YAML::PROD_DQUOTED_COMMON:
638 case Teuchos::YAML::PROD_SQUOTED_COMMON:
639 case Teuchos::YAML::PROD_ANY_COMMON:
640 case Teuchos::YAML::PROD_COMMON_SPACE:
641 case Teuchos::YAML::PROD_COMMON_OTHER:
642 case Teuchos::YAML::PROD_BSCALAR_HEAD_OTHER: {
643 swap(result_any, rhs.at(0));
647 case Teuchos::YAML::PROD_DQUOTED_NEXT:
648 case Teuchos::YAML::PROD_SQUOTED_NEXT:
649 case Teuchos::YAML::PROD_ANY_NEXT:
650 case Teuchos::YAML::PROD_SCALAR_TAIL_NEXT:
651 case Teuchos::YAML::PROD_SPACE_STAR_NEXT:
652 case Teuchos::YAML::PROD_SPACE_PLUS_NEXT:
653 case Teuchos::YAML::PROD_BSCALAR_HEAD_NEXT: {
655 "leading characters in " << prod <<
": any was empty\n");
656 swap(result_any, rhs.at(0));
657 std::string& str = any_ref_cast<std::string>(result_any);
658 str += any_cast<char>(rhs.at(1));
661 case Teuchos::YAML::PROD_DQUOTED_EMPTY:
662 case Teuchos::YAML::PROD_SQUOTED_EMPTY:
663 case Teuchos::YAML::PROD_ANY_EMPTY:
664 case Teuchos::YAML::PROD_DESCAPE_EMPTY:
665 case Teuchos::YAML::PROD_SESCAPE_EMPTY:
666 case Teuchos::YAML::PROD_SCALAR_TAIL_EMPTY:
667 case Teuchos::YAML::PROD_SPACE_STAR_EMPTY:
668 case Teuchos::YAML::PROD_BSCALAR_HEAD_EMPTY: {
669 result_any = std::string();
672 case Teuchos::YAML::PROD_DESCAPED_DQUOT:
673 case Teuchos::YAML::PROD_SQUOTED_DQUOT:
674 case Teuchos::YAML::PROD_ANY_DQUOT: {
678 case Teuchos::YAML::PROD_DESCAPED_SLASH:
679 case Teuchos::YAML::PROD_SQUOTED_SLASH:
680 case Teuchos::YAML::PROD_ANY_SLASH: {
684 case Teuchos::YAML::PROD_SCALAR_TAIL_SQUOT:
685 case Teuchos::YAML::PROD_DQUOTED_SQUOT:
686 case Teuchos::YAML::PROD_ANY_SQUOT: {
690 case Teuchos::YAML::PROD_COMMON_COLON: {
694 case Teuchos::YAML::PROD_SCALAR_TAIL_DOT:
695 case Teuchos::YAML::PROD_COMMON_DOT: {
699 case Teuchos::YAML::PROD_SCALAR_TAIL_DASH:
700 case Teuchos::YAML::PROD_COMMON_DASH:
701 case Teuchos::YAML::PROD_BSCALAR_HEAD_DASH: {
705 case Teuchos::YAML::PROD_COMMON_PIPE: {
709 case Teuchos::YAML::PROD_COMMON_LSQUARE: {
713 case Teuchos::YAML::PROD_COMMON_RSQUARE: {
717 case Teuchos::YAML::PROD_COMMON_LCURLY: {
721 case Teuchos::YAML::PROD_COMMON_RCURLY: {
725 case Teuchos::YAML::PROD_COMMON_RANGLE: {
729 case Teuchos::YAML::PROD_COMMON_COMMA: {
733 case Teuchos::YAML::PROD_COMMON_PERCENT: {
737 case Teuchos::YAML::PROD_COMMON_EXCL: {
743 void map_first_item(any& result_any, any& first_item) {
744 ParameterList& list = make_any_ref<ParameterList>(result_any);
746 PLPair& pair = any_ref_cast<PLPair>(first_item);
747 safe_set_entry(list, pair.key, pair.value);
749 void map_next_item(any& result_any, any& items, any& next_item) {
751 swap(result_any, items);
752 ParameterList& list = any_ref_cast<ParameterList>(result_any);
753 PLPair& pair = any_ref_cast<PLPair>(next_item);
754 safe_set_entry(list, pair.key, pair.value);
756 void map_item(any& result_any, any& key_any, any& value_any,
int scalar_type = -1) {
758 PLPair& result = make_any_ref<PLPair>(result_any);
760 std::string& key = any_ref_cast<Scalar>(key_any).text;
761 swap(result.key, key);
763 resolve_map_value(value_any, scalar_type);
764 if (value_any.type() ==
typeid(
bool)) {
765 bool value = any_cast<bool>(value_any);
766 result.value = ParameterEntry(value);
767 }
else if (value_any.type() ==
typeid(
int)) {
768 int value = any_cast<int>(value_any);
769 result.value = ParameterEntry(value);
770 }
else if (value_any.type() ==
typeid(
long long)) {
771 long long value = any_cast<long long>(value_any);
772 result.value = ParameterEntry(value);
773 }
else if (value_any.type() ==
typeid(
double)) {
774 double value = any_cast<double>(value_any);
775 result.value = ParameterEntry(value);
776 }
else if (value_any.type() ==
typeid(std::string)) {
777 std::string& value = any_ref_cast<std::string >(value_any);
778 result.value = ParameterEntry(value);
779 }
else if (value_any.type() ==
typeid(Array<int>)) {
780 Array<int>& value = any_ref_cast<Array<int> >(value_any);
781 result.value = ParameterEntry(value);
782 }
else if (value_any.type() ==
typeid(Array<long long>)) {
783 Array<long long>& value = any_ref_cast<Array<long long> >(value_any);
784 result.value = ParameterEntry(value);
785 }
else if (value_any.type() ==
typeid(Array<double>)) {
786 Array<double>& value = any_ref_cast<Array<double> >(value_any);
787 result.value = ParameterEntry(value);
788 }
else if (value_any.type() ==
typeid(Array<std::string>)) {
789 Array<std::string>& value = any_ref_cast<Array<std::string> >(value_any);
790 result.value = ParameterEntry(value);
791 }
else if (value_any.type() ==
typeid(TwoDArray<int>)) {
792 TwoDArray<int>& value = any_ref_cast<TwoDArray<int> >(value_any);
793 result.value = ParameterEntry(value);
794 }
else if (value_any.type() ==
typeid(TwoDArray<long long>)) {
795 TwoDArray<long long>& value = any_ref_cast<TwoDArray<long long> >(value_any);
796 result.value = ParameterEntry(value);
797 }
else if (value_any.type() ==
typeid(TwoDArray<double>)) {
798 TwoDArray<double>& value = any_ref_cast<TwoDArray<double> >(value_any);
799 result.value = ParameterEntry(value);
800 }
else if (value_any.type() ==
typeid(TwoDArray<std::string>)) {
801 TwoDArray<std::string>& value = any_ref_cast<TwoDArray<std::string> >(value_any);
802 result.value = ParameterEntry(value);
803 }
else if (value_any.type() ==
typeid(ParameterList)) {
804 ParameterList& value = any_ref_cast<ParameterList>(value_any);
805 ParameterList& result_pl = result.value.setList();
806 swap(result_pl, value);
807 result_pl.setName(result.key);
809 std::string msg =
"unexpected YAML map value type ";
810 msg += value_any.type().name();
811 msg +=
" for key \"";
814 throw ParserFail(msg);
817 void resolve_map_value(any& value_any,
int scalar_type = -1)
const {
818 if (value_any.type() ==
typeid(Scalar)) {
819 Scalar& scalar_value = any_ref_cast<Scalar>(value_any);
820 if (scalar_type == -1) {
821 scalar_type = scalar_value.infer_type();
823 if (scalar_type == Scalar::BOOL) {
824 value_any = parse_as<bool>(scalar_value.text);
825 }
else if (scalar_type == Scalar::INT) {
826 value_any = parse_as<int>(scalar_value.text);
827 }
else if (scalar_type == Scalar::LONG_LONG) {
828 value_any = parse_as<long long>(scalar_value.text);
829 }
else if (scalar_type == Scalar::DOUBLE) {
830 value_any = parse_as<double>(scalar_value.text);
832 value_any = scalar_value.text;
834 }
else if (value_any.type() ==
typeid(Array<Scalar>)) {
835 Array<Scalar>& scalars = any_ref_cast<Array<Scalar> >(value_any);
836 if (scalar_type == -1) {
837 if (scalars.size() == 0) {
838 throw ParserFail(
"implicitly typed arrays can't be empty\n"
839 "(need to determine their element type)\n");
843 scalar_type = Scalar::INT;
844 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
845 scalar_type = std::min(scalar_type, scalars[i].infer_type());
848 if (scalar_type == Scalar::INT) {
849 Array<int> result(scalars.size());
850 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
851 result[i] = parse_as<int>(scalars[i].text);
854 }
else if (scalar_type == Scalar::LONG_LONG) {
855 Array<long long> result(scalars.size());
856 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
857 result[i] = parse_as<long long>(scalars[i].text);
860 }
else if (scalar_type == Scalar::DOUBLE) {
861 Array<double> result(scalars.size());
862 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
863 result[i] = parse_as<double>(scalars[i].text);
866 }
else if (scalar_type == Scalar::STRING) {
867 Array<std::string> result(scalars.size());
868 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
869 result[i] = scalars[i].text;
873 }
else if (value_any.type() ==
typeid(Array<Array<Scalar>>)) {
874 Array<Array<Scalar>>& scalars = any_ref_cast<Array<Array<Scalar>> >(value_any);
875 if (scalar_type == -1) {
876 if (scalars.size() == 0) {
877 throw ParserFail(
"implicitly typed 2D arrays can't be empty\n"
878 "(need to determine their element type)\n");
882 scalar_type = Scalar::INT;
883 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
884 if (scalars[0].size() == 0) {
885 throw ParserFail(
"implicitly typed 2D arrays can't have empty rows\n"
886 "(need to determine their element type)\n");
888 if (scalars[i].size() != scalars[0].size()) {
889 throw ParserFail(
"2D array: sub-arrays are different sizes");
891 for (Teuchos_Ordinal j = 0; j < scalars[i].size(); ++j) {
892 int item_type = scalars[i][j].infer_type();
893 scalar_type = std::min(scalar_type, item_type);
897 if (scalar_type == Scalar::INT) {
898 TwoDArray<int> result(scalars.size(), scalars[0].size());
899 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
900 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
901 result(i, j) = parse_as<int>(scalars[i][j].text);
905 }
else if (scalar_type == Scalar::LONG_LONG) {
906 TwoDArray<long long> result(scalars.size(), scalars[0].size());
907 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
908 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
909 result(i, j) = parse_as<long long>(scalars[i][j].text);
913 }
else if (scalar_type == Scalar::DOUBLE) {
914 TwoDArray<double> result(scalars.size(), scalars[0].size());
915 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
916 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
917 result(i, j) = parse_as<double>(scalars[i][j].text);
921 }
else if (scalar_type == Scalar::STRING) {
922 TwoDArray<std::string> result(scalars.size(), scalars[0].size());
923 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
924 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
925 result(i, j) = scalars[i][j].text;
932 int interpret_tag(any& tag_any) {
933 if (tag_any.type() !=
typeid(std::string))
return -1;
934 std::string& text = any_ref_cast<std::string>(tag_any);
935 if (text.find(
"bool") != std::string::npos)
return Scalar::BOOL;
936 else if (text.find(
"int") != std::string::npos)
return Scalar::INT;
937 else if (text.find(
"double") != std::string::npos)
return Scalar::DOUBLE;
938 else if (text.find(
"string") != std::string::npos)
return Scalar::STRING;
940 std::string msg =
"Unable to parse type tag \"";
943 throw ParserFail(msg);
946 void seq_first_item(any& result_any, any& first_any) {
948 if (first_any.type() ==
typeid(Scalar)) {
949 Array<Scalar>& a = make_any_ref<Array<Scalar> >(result_any);
950 Scalar& v = any_ref_cast<Scalar>(first_any);
951 a.push_back(Scalar());
953 }
else if (first_any.type() ==
typeid(Array<Scalar>)) {
954 Array<Array<Scalar>>& a = make_any_ref<Array<Array<Scalar>> >(result_any);
955 Array<Scalar>& v = any_ref_cast<Array<Scalar> >(first_any);
956 a.push_back(Array<Scalar>());
960 "bug in YAMLParameterList::Reader: unexpected type for first sequence item");
963 void seq_next_item(any& result_any, any& items, any& next_item) {
965 swap(result_any, items);
966 if (result_any.type() ==
typeid(Array<Scalar>)) {
967 Array<Scalar>& a = any_ref_cast<Array<Scalar> >(result_any);
968 Scalar& val = any_ref_cast<Scalar>(next_item);
969 a.push_back(Scalar());
971 }
else if (result_any.type() ==
typeid(Array<Array<Scalar>>)) {
972 Array<Array<Scalar>>& a = any_ref_cast<Array<Array<Scalar>> >(result_any);
973 Array<Scalar>& v = any_ref_cast<Array<Scalar> >(next_item);
974 a.push_back(Array<Scalar>());
978 "bug in YAMLParameterList::Reader: unexpected type for next sequence item");
982 void handle_block_scalar(
983 std::size_t parent_indent_level,
984 std::string
const& header,
985 std::string
const& leading_empties_or_comments,
986 std::string
const& rest,
987 std::string& content,
988 std::string& comment) {
991 char chomping_indicator;
992 std::size_t indentation_indicator = 0;
994 std::stringstream ss(header.substr(1,std::string::npos));
995 if (header.size() > 1 && my_isdigit(header[1])) {
996 ss >> indentation_indicator;
998 indentation_indicator += parent_indent_level;
1000 if (!(ss >> chomping_indicator)) chomping_indicator =
'\0';
1003 std::size_t first_newline = leading_empties_or_comments.find_first_of(
"\r\n");
1004 std::string newline;
1005 if (first_newline > 0 && leading_empties_or_comments[first_newline - 1] ==
'\r') {
1010 std::size_t keep_beg = first_newline + 1 - newline.size();
1011 if (leading_empties_or_comments[0] ==
'#') {
1012 comment = leading_empties_or_comments.substr(1, keep_beg);
1015 std::size_t content_beg = leading_empties_or_comments.find_first_not_of(
"\r\n ");
1016 if (content_beg == std::string::npos) content_beg = leading_empties_or_comments.size();
1017 std::size_t newline_before_content = leading_empties_or_comments.rfind(
"\n", content_beg);
1018 std::size_t num_indent_spaces = (content_beg - newline_before_content) - 1;
1021 if (indentation_indicator > 0) {
1024 "Indentation indicator " << indentation_indicator <<
" > leading spaces " << num_indent_spaces);
1025 num_indent_spaces = indentation_indicator;
1028 content = leading_empties_or_comments.substr(keep_beg, std::string::npos);
1037 auto last_newline = content.find_last_of(
"\n", content.size() - 2);
1038 if (last_newline == std::string::npos)
break;
1039 std::size_t num_spaces = 0;
1040 for (
auto ispace = last_newline + 1;
1041 ispace < content.size() && content[ispace] ==
' ';
1045 if (num_spaces >= num_indent_spaces)
break;
1046 content.erase(content.begin() + last_newline + 1, content.end());
1049 std::size_t unindent_pos = 0;
1051 std::size_t next_newline = content.find_first_of(
"\n", unindent_pos);
1052 if (next_newline == std::string::npos)
break;
1053 std::size_t start_cut = next_newline + 1;
1055 if (style ==
'>') start_cut -= newline.size();
1056 std::size_t end_cut = next_newline + 1;
1059 while (end_cut < content.size() && content[end_cut] ==
' ') {
1063 end_cut = std::min(next_newline + 1 + num_indent_spaces, end_cut);
1065 content = content.substr(0, start_cut) +
1066 content.substr(end_cut, std::string::npos);
1067 unindent_pos = start_cut;
1069 if (chomping_indicator !=
'+') {
1070 content = remove_trailing_whitespace_and_newlines(content);
1071 if (chomping_indicator !=
'-') content += newline;
1075 content = content.substr(newline.size(), std::string::npos);
1096void updateParametersFromYamlCString(
const char*
const data,
1106 paramList->setParameters(*updated);
1110 paramList->setParametersNotAlreadySet(*updated);
1114void updateParametersFromYamlString(
const std::string&
yamlData,
1117 const std::string& name)
1141 return YAMLParameterList::parseYamlStream(
ss);
1144void writeParameterListToYamlOStream(
1152void writeParameterListToYamlFile(
1160std::string convertXmlToYaml(
const std::string&
xmlFileName)
1172 yamlFileName = xmlFileName.substr(0, xmlFileName.length() - 4) +
".yaml";
1174 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
1175 return yamlFileName;
1178void convertXmlToYaml(
const std::string& xmlFileName,
const std::string& yamlFileName)
1181 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
1184void convertXmlToYaml(std::istream& xmlStream, std::ostream& yamlStream)
1187 std::istreambuf_iterator<char> begin(xmlStream);
1188 std::istreambuf_iterator<char> end;
1189 std::string xmlString(begin, end);
1191 YAMLParameterList::writeYamlStream(yamlStream, *toConvert);
1194namespace YAMLParameterList
1199#ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
1200 auto yaml_input = ::YAML::LoadAll(text);
1201 return readParams(yaml_input);
1204 Teuchos::YAMLParameterList::Reader reader;
1205 reader.read_string(result, text, name);
1206 ParameterList& pl = any_ref_cast<ParameterList>(result);
1213#ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
1214 auto yaml_input = ::YAML::LoadAllFromFile(yamlFile);
1215 return readParams(yaml_input);
1218 Teuchos::YAMLParameterList::Reader reader;
1219 reader.read_file(result, yamlFile);
1220 ParameterList& pl = any_ref_cast<ParameterList>(result);
1227#ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
1228 auto yaml_input = ::YAML::LoadAll(yaml);
1229 return readParams(yaml_input);
1232 Teuchos::YAMLParameterList::Reader reader;
1233 reader.read_stream(result, yaml,
"parseYamlStream");
1234 ParameterList& pl = any_ref_cast<ParameterList>(result);
1242#ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
1249 for(
size_t i = 0; i < lists.size(); i++)
1251 processMapNode(lists[i], *pl,
true);
1258 if (node.Type() != ::YAML::NodeType::Map)
1260 throw YamlStructureError(
"All top-level elements of the YAML file must be maps.");
1264 parent.
setName(node.begin()->first.as<std::string>());
1265 processMapNode(node.begin()->second, parent);
1269 for (::YAML::const_iterator i = node.begin(); i != node.end(); i++)
1272 if(i->first.Type() != ::YAML::NodeType::Scalar)
1274 throw YamlKeyError(
"Keys must be YAML scalars (int, double, or string)");
1277 const std::string key = quoted_as<std::string>(i->first);
1278 processKeyValueNode(key, i->second, parent, topLevel);
1283void processKeyValueNode(
const std::string& key, const ::YAML::Node& node,
Teuchos::ParameterList& parent,
bool topLevel)
1287 if(node.Type() == ::YAML::NodeType::Scalar)
1291 safe_set_entry<int>(parent, key, quoted_as<int>(node));
1297 safe_set_entry<long long>(parent, key, quoted_as<long long>(node));
1303 safe_set_entry<double>(parent, key, quoted_as<double>(node));
1309 bool raw_bool = quoted_as<bool>(node);
1317 std::string raw_string = quoted_as<std::string>(node);
1318 if (is_parseable_as<bool>(raw_string))
1320 safe_set_entry<bool>(parent, key, raw_bool);
1324 safe_set_entry<std::string>(parent, key, raw_string);
1329 safe_set_entry<std::string>(parent, key, quoted_as<std::string>(node));
1335 else if(node.Type() == ::YAML::NodeType::Map)
1339 processMapNode(node, parent);
1344 processMapNode(node, sublist);
1347 else if(node.Type() == ::YAML::NodeType::Sequence)
1349 int ndim = getYamlArrayDim(node);
1352 ::YAML::Node
const& first_value = *(node.begin());
1355 quoted_as<int>(first_value);
1356 safe_set_entry<Teuchos::Array<int>>(parent, key, getYamlArray<int>(node));
1362 quoted_as<double>(first_value);
1363 safe_set_entry<Teuchos::Array<double>>(parent, key, getYamlArray<double>(node));
1369 quoted_as<std::string>(first_value);
1370 safe_set_entry<Teuchos::Array<std::string>>(parent, key, getYamlArray<std::string>(node));
1374 throw YamlSequenceError(std::string(
"Array \"") + key +
"\" must contain int, double, bool or string");
1381 bool is_ragged = checkYamlTwoDArrayIsRagged(node);
1382 ::YAML::Node
const& first_value = *(node.begin()->begin());
1385 quoted_as<int>(first_value);
1388 safe_set_entry<arr_t>(parent, key, getYaml2DRaggedArray<arr_t, int>(node, ndim, key));
1390 safe_set_entry<Teuchos::TwoDArray<int>>(parent, key, getYamlTwoDArray<int>(node));
1397 quoted_as<double>(first_value);
1400 safe_set_entry<arr_t>(parent, key, getYaml2DRaggedArray<arr_t, double>(node, ndim, key));
1402 safe_set_entry<Teuchos::TwoDArray<double>>(parent, key, getYamlTwoDArray<double>(node));
1409 quoted_as<std::string>(first_value);
1412 safe_set_entry<arr_t>(parent, key, getYaml2DRaggedArray<arr_t, std::string>(node, ndim, key));
1414 safe_set_entry<Teuchos::TwoDArray<std::string>>(parent, key, getYamlTwoDArray<std::string>(node));
1419 throw YamlSequenceError(std::string(
"TwoDArray \"") + key +
"\" must contain int, double, bool or string");
1426 ::YAML::Node
const& first_value = *(node.begin()->begin()->begin());
1429 quoted_as<int>(first_value);
1431 safe_set_entry<arr_t>(parent, key, getYaml3DArray<arr_t, int>(node, ndim, key));
1437 quoted_as<double>(first_value);
1439 safe_set_entry<arr_t>(parent, key, getYaml3DArray<arr_t, double>(node, ndim, key));
1446 quoted_as<std::string>(first_value);
1448 safe_set_entry<arr_t>(parent, key, getYaml3DArray<arr_t, std::string>(node, ndim, key));
1453 throw YamlSequenceError(std::string(
"3DArray \"") + key +
"\" must contain int, double, bool or string");
1459 else if(node.Type() == ::YAML::NodeType::Null)
1467 throw YamlUndefinedNodeError(
"Value type in a key-value pair must be one of: int, double, string, array, sublist.");
1476 std::ios_base::fmtflags flags = yaml.flags();
1478 std::ostringstream testStream;
1479 testStream.flags(flags);
1481 testStream << testVal;
1482 bool popFlags =
false;
1483 if(testStream.str() ==
"1")
1489 std::cout <<
"Warning: yaml stream format flags would confuse double with integer value with int.\n";
1490 std::cout <<
"Setting std::ios::showpoint on the stream to fix this (will restore flags when done)\n";
1491 std::ios_base::fmtflags flagsCopy = flags;
1492 flagsCopy |= std::ios::showpoint;
1495 yaml <<
"%YAML 1.1\n---\n";
1496 yaml << pl.
name() <<
':';
1503 writeParameterList(pl, yaml, 2);
1515 std::ofstream yaml(yamlFile.c_str());
1522 yaml << std::scientific << std::setprecision(17);
1523 writeYamlStream(yaml, pl);
1535 for(PLIter it = pl.
begin(); it != pl.
end(); it++)
1537 writeParameter(pl.
name(it), pl.
entry(it), yaml, indentLevel);
1542template <
typename T>
1544 static void write(T
const& x, std::ostream& stream) {
1550struct YamlWrite<double> {
1551 static void write(
double const& x, std::ostream& stream) {
1552 generalWriteDouble(x, stream);
1557struct YamlWrite<std::string> {
1558 static void write(std::string
const& x, std::ostream& stream) {
1559 generalWriteString(x, stream);
1563template <
typename T>
1568 for (i = 0; i < arr.getNumRows(); ++i)
1570 if (i) stream <<
", ";
1572 for (j = 0; j < arr.getNumCols(); ++j)
1574 if (j) stream <<
", ";
1575 YamlWrite<T>::write(arr(i, j), stream);
1582void writeParameter(
const std::string& paramName,
const Teuchos::ParameterEntry& entry, std::ostream& yaml,
int indentLevel)
1584 for(
int i = 0; i < indentLevel; i++)
1588 generalWriteString(paramName, yaml);
1601 for(
int i = 0; i < arr.size(); i++)
1604 if(i != arr.size() - 1)
1611 for(
int i = 0; i < arr.size(); i++)
1614 if(i != arr.size() - 1)
1621 for(
int i = 0; i < arr.size(); i++)
1623 generalWriteDouble(arr[i], yaml);
1624 if(i != arr.size() - 1)
1631 for(
int i = 0; i < arr.size(); i++)
1633 generalWriteString(arr[i], yaml);
1634 if(i != arr.size() - 1)
1644 writeYamlTwoDArray<int>(
1649 writeYamlTwoDArray<long long>(
1654 writeYamlTwoDArray<double>(
1659 writeYamlTwoDArray<std::string>(
1663 else if(entry.
isType<
int>())
1665 yaml << Teuchos::getValue<int>(entry);
1667 else if(entry.
isType<
long long>())
1669 yaml << Teuchos::getValue<long long>(entry);
1671 else if(entry.
isType<
double>())
1675 else if(entry.
isType<std::string>())
1678 if(strchr(str.c_str(),
'\n'))
1684 std::size_t first_non_newline_pos = str.find_first_not_of(
"\r\n");
1685 if (first_non_newline_pos != std::string::npos &&
1686 str[first_non_newline_pos] ==
' ') {
1689 if (str[str.size() - 1] !=
'\n') yaml <<
"-";
1695 size_t next = str.find(
'\n', index);
1696 for(
int i = 0; i < indentLevel + 2; i++)
1700 if(next == std::string::npos)
1702 yaml << str.substr(index, std::string::npos);
1707 yaml << str.substr(index, next - index) <<
'\n';
1714 generalWriteString(str, yaml);
1717 else if(entry.
isType<
bool>())
1719 yaml << (Teuchos::getValue<bool>(entry) ?
"true" :
"false");
1724void generalWriteString(
const std::string& str, std::ostream& yaml)
1727 if(stringNeedsQuotes(str))
1730 for (std::size_t i = 0; i < str.size(); ++i) {
1731 if (str[i] ==
'\'') yaml <<
"''";
1732 else yaml << str[i];
1742void generalWriteDouble(
double d, std::ostream& yaml)
1747static bool containsSpecialCharacters(std::string
const& s) {
1748 char const*
const control_chars =
":'{}[],&*#?|<>=!%@\\";
1749 return s.find_first_of(control_chars) != std::string::npos;
1752bool stringNeedsQuotes(
const std::string& s)
1755 containsSpecialCharacters(s) ||
1756 is_parseable_as<bool>(s) ||
1757 is_parseable_as<int>(s) ||
1758 is_parseable_as<long long>(s) ||
1759 is_parseable_as<double>(s);
Declares Teuchos::Reader.
A thin wrapper around the Teuchos Array class that allows for 2 dimensional arrays.
Simple helper functions that make it easy to read and write XML to and from a parameterlist.
A TeuchosParser Language for a subset of YAML.
Simple helper functions that make it easy to read and write Yaml to and from a parameterlist.
Functions to convert between ParameterList and YAML.
This object is held as the "value" in the Teuchos::ParameterList std::map.
bool isType() const
Test the type of the data being contained.
bool isTwoDArray() const
Test if the type of data being contained is a Teuchos::TwoDArray.
bool isArray() const
Test if the type of data being contained is a Teuchos::Array.
bool isList() const
Return whether or not the value itself is a list.
A list of parameters of arbitrary type.
const ParameterEntry & entry(ConstIterator i) const
Access to ParameterEntry (i.e., returns i->second)
ConstIterator end() const
An iterator pointing beyond the last entry.
Ordinal numParams() const
Get the number of stored parameters.
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,...
const std::string & name() const
The name of this ParameterList.
ConstIterator begin() const
An iterator pointing to the first entry.
ParameterList & setName(const std::string &name)
Set the name of *this list.
Tries to create LALR(1) parser tables for a given grammar.
Smart reference counting pointer class for automatic garbage collection.
The main class for users to read text using TeuchosParser.
Reader(ReaderTablesPtr tables_in)
Constructor: accepts an RCP to ReaderTables.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
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.