62std::string remove_trailing_whitespace(std::string
const& in) {
63 std::size_t new_end = 0;
64 for (std::size_t ri = 0; ri < in.size(); ++ri) {
65 std::size_t i = in.size() - 1 - ri;
66 if (in[i] !=
' ' && in[i] !=
'\t') {
71 return in.substr(0, new_end);
74std::string remove_trailing_whitespace_and_newlines(std::string
const& in) {
75 std::size_t new_end = 0;
76 for (std::size_t ri = 0; ri < in.size(); ++ri) {
77 std::size_t i = in.size() - 1 - ri;
78 if (in[i] !=
' ' && in[i] !=
'\t' && in[i] !=
'\n' && in[i] !=
'\r') {
83 return in.substr(0, new_end);
87bool is_parseable_as(std::string
const& text) {
88 std::istringstream ss(text);
90 ss >> std::noskipws >> val;
91 return ss.eof() && !ss.fail();
95bool is_parseable_as<int>(std::string
const& text) {
96 std::istringstream ss(text);
99 ss >> std::noskipws >> val;
100 return ss.eof() && !ss.fail() &&
101 (val >= LL(std::numeric_limits<int>::min())) &&
102 (val <= LL(std::numeric_limits<int>::max()));
106T parse_as(std::string
const& text) {
107 std::istringstream ss(text);
114static char my_tolower(
char ch)
116 return std::tolower(
static_cast<unsigned char>(ch));
120static bool my_isdigit(
char ch)
122 return std::isdigit(
static_cast<unsigned char>(ch));
126bool is_parseable_as<bool>(std::string
const& text) {
128 for (std::size_t i = 0; i < text.size(); ++i) {
129 lower.push_back(my_tolower(text[i]));
131 return lower ==
"true" || lower ==
"yes" ||
132 lower ==
"false" || lower ==
"no";
136bool parse_as<bool>(std::string
const& text) {
138 for (std::size_t i = 0; i < text.size(); ++i) {
139 lower.push_back(my_tolower(text[i]));
141 return !(lower ==
"false" || lower ==
"no");
146 ParameterEntry value;
167 int infer_type()
const {
168 if (tag_type != -1) {
174 if (is_parseable_as<bool>(text)) {
177 if (is_parseable_as<int>(text)) {
180 if (is_parseable_as<long long>(text)) {
183 if (is_parseable_as<double>(text)) {
190bool operator==(Scalar
const&, Scalar
const&) {
return false; }
191std::ostream& operator<<(std::ostream& os, Scalar
const&) {
return os; }
195 "Parameter \"" << name_in <<
"\" already exists in list \"" << list.name() <<
"\"\n");
196 list.setEntry(name_in, entry_in);
199namespace YAMLParameterList {
201class Reader :
public Teuchos::Reader {
203 Reader():Teuchos::Reader(Teuchos::YAML::ask_reader_tables()) {}
210 virtual void at_shift(any& result_any,
int token, std::string& text) {
213 case Teuchos::YAML::TOK_NEWLINE: {
218 case Teuchos::YAML::TOK_SPACE:
219 case Teuchos::YAML::TOK_OTHER: {
220 result_any = text.at(0);
225 virtual void at_reduce(any& result_any,
int prod, std::vector<any>& rhs) {
228 case Teuchos::YAML::PROD_DOC:
229 case Teuchos::YAML::PROD_DOC2: {
230 std::size_t offset = prod == Teuchos::YAML::PROD_DOC2 ? 1 : 0;
232 swap(result_any, rhs.at(offset));
236 case Teuchos::YAML::PROD_TOP_BMAP: {
240 any& pair_rhs_any = pair.value.getAny(
false);
241 result_any = pair_rhs_any;
244 case Teuchos::YAML::PROD_TOP_FIRST: {
245 if (rhs.at(0).type() ==
typeid(ParameterList)) {
246 swap(result_any, rhs.at(0));
250 case Teuchos::YAML::PROD_TOP_NEXT: {
251 if (rhs.at(1).type() ==
typeid(ParameterList)) {
253 "Can't specify multiple top-level ParameterLists in one YAML file!\n");
254 swap(result_any, rhs.at(1));
256 swap(result_any, rhs.at(0));
260 case Teuchos::YAML::PROD_BMAP_FIRST:
261 case Teuchos::YAML::PROD_FMAP_FIRST: {
263 map_first_item(result_any, rhs.at(0));
267 case Teuchos::YAML::PROD_BMAP_NEXT: {
268 map_next_item(result_any, rhs.at(0), rhs.at(1));
271 case Teuchos::YAML::PROD_FMAP_NEXT: {
272 map_next_item(result_any, rhs.at(0), rhs.at(3));
275 case Teuchos::YAML::PROD_BMAP_SCALAR:
276 case Teuchos::YAML::PROD_FMAP_SCALAR:
277 case Teuchos::YAML::PROD_FMAP_FMAP:
278 case Teuchos::YAML::PROD_FMAP_FSEQ: {
279 int scalar_type = interpret_tag(rhs.at(3));
280 map_item(result_any, rhs.at(0), rhs.at(4), scalar_type);
283 case Teuchos::YAML::PROD_BMAP_BSCALAR: {
284 map_item(result_any, rhs.at(0), rhs.at(3), Scalar::STRING);
287 case Teuchos::YAML::PROD_BMAP_BVALUE: {
288 map_item(result_any, rhs.at(0), rhs.at(4));
291 case Teuchos::YAML::PROD_BVALUE_EMPTY: {
292 result_any = ParameterList();
295 case Teuchos::YAML::PROD_BVALUE_BMAP:
296 case Teuchos::YAML::PROD_BVALUE_BSEQ: {
297 swap(result_any, rhs.at(1));
300 case Teuchos::YAML::PROD_BMAP_FMAP: {
301 map_item(result_any, rhs.at(0), rhs.at(4));
304 case Teuchos::YAML::PROD_BMAP_FSEQ: {
306 rhs.at(4).type() ==
typeid(Array<Array<Scalar>>));
307 int scalar_type = interpret_tag(rhs.at(3));
308 map_item(result_any, rhs.at(0), rhs.at(4), scalar_type);
311 case Teuchos::YAML::PROD_BSEQ_FIRST: {
312 seq_first_item(result_any, rhs.at(0));
315 case Teuchos::YAML::PROD_BSEQ_NEXT: {
316 seq_next_item(result_any, rhs.at(0), rhs.at(1));
319 case Teuchos::YAML::PROD_BSEQ_SCALAR: {
320 swap(result_any, rhs.at(3));
322 scalar.tag_type = interpret_tag(rhs.at(2));
325 case Teuchos::YAML::PROD_BSEQ_BSCALAR: {
326 swap(result_any, rhs.at(2));
329 case Teuchos::YAML::PROD_BSEQ_BMAP:
330 case Teuchos::YAML::PROD_BSEQ_BMAP_TRAIL:
331 case Teuchos::YAML::PROD_BSEQ_FMAP: {
332 throw ParserFail(
"Can't interpret a map inside a sequence as a Teuchos Parameter");
334 case Teuchos::YAML::PROD_BSEQ_BSEQ: {
335 swap(result_any, rhs.at(3));
338 case Teuchos::YAML::PROD_BSEQ_BSEQ_TRAIL: {
339 swap(result_any, rhs.at(4));
342 case Teuchos::YAML::PROD_BSEQ_FSEQ: {
343 swap(result_any, rhs.at(3));
346 case Teuchos::YAML::PROD_FMAP: {
347 swap(result_any, rhs.at(2));
350 case Teuchos::YAML::PROD_FMAP_EMPTY: {
351 result_any = ParameterList();
354 case Teuchos::YAML::PROD_FSEQ: {
355 swap(result_any, rhs.at(2));
357 result_any.type() ==
typeid(Array<Array<Scalar>>));
360 case Teuchos::YAML::PROD_FSEQ_EMPTY: {
361 result_any = Array<Scalar>();
364 case Teuchos::YAML::PROD_FSEQ_FIRST: {
365 seq_first_item(result_any, rhs.at(0));
368 case Teuchos::YAML::PROD_FSEQ_NEXT: {
369 seq_next_item(result_any, rhs.at(0), rhs.at(3));
372 case Teuchos::YAML::PROD_FSEQ_SCALAR: {
373 swap(result_any, rhs.at(1));
375 scalar.tag_type = interpret_tag(rhs.at(0));
378 case Teuchos::YAML::PROD_FSEQ_FSEQ:
379 case Teuchos::YAML::PROD_FSEQ_FMAP: {
380 swap(result_any, rhs.at(1));
383 case Teuchos::YAML::PROD_SCALAR_QUOTED:
384 case Teuchos::YAML::PROD_MAP_SCALAR_QUOTED: {
385 swap(result_any, rhs.at(0));
388 case Teuchos::YAML::PROD_SCALAR_RAW:
389 case Teuchos::YAML::PROD_MAP_SCALAR_RAW: {
394 if (prod == Teuchos::YAML::PROD_MAP_SCALAR_RAW) {
397 scalar.text = remove_trailing_whitespace(scalar.text);
398 scalar.source = Scalar::RAW;
399 scalar.tag_type = -1;
402 case Teuchos::YAML::PROD_SCALAR_HEAD_OTHER:
403 case Teuchos::YAML::PROD_SCALAR_HEAD_DOT:
404 case Teuchos::YAML::PROD_SCALAR_HEAD_DASH:
405 case Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT: {
407 if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_OTHER) offset = 0;
408 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT) offset = 2;
412 if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT) result +=
'.';
413 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DASH) result +=
'-';
414 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT) result +=
"..";
418 case Teuchos::YAML::PROD_SCALAR_DQUOTED:
419 case Teuchos::YAML::PROD_SCALAR_SQUOTED: {
423 scalar.text += first;
425 if (prod == Teuchos::YAML::PROD_SCALAR_DQUOTED) {
426 scalar.source = Scalar::DQUOTED;
427 }
else if (prod == Teuchos::YAML::PROD_SCALAR_SQUOTED) {
428 scalar.source = Scalar::SQUOTED;
430 scalar.tag_type = -1;
433 case Teuchos::YAML::PROD_MAP_SCALAR_ESCAPED_EMPTY: {
434 result_any = std::string();
437 case Teuchos::YAML::PROD_MAP_SCALAR_ESCAPED_NEXT: {
438 swap(result_any, rhs.at(0));
444 case Teuchos::YAML::PROD_TAG: {
445 swap(result_any, rhs.at(2));
448 case Teuchos::YAML::PROD_BSCALAR: {
449 std::size_t parent_indent_level =
450 this->symbol_indentation_stack.at(
451 this->symbol_indentation_stack.size() - 5);
453 std::string& leading_empties_or_comments =
460 header, leading_empties_or_comments, rest,
464 case Teuchos::YAML::PROD_BSCALAR_FIRST: {
465 swap(result_any, rhs.at(0));
469 case Teuchos::YAML::PROD_BSCALAR_NEXT:
470 case Teuchos::YAML::PROD_BSCALAR_LINE:
471 case Teuchos::YAML::PROD_DESCAPE_NEXT:
472 case Teuchos::YAML::PROD_SESCAPE_NEXT: {
473 swap(result_any, rhs.at(0));
478 case Teuchos::YAML::PROD_BSCALAR_INDENT: {
479 swap(result_any, rhs.at(1));
482 case Teuchos::YAML::PROD_BSCALAR_HEADER_LITERAL:
483 case Teuchos::YAML::PROD_BSCALAR_HEADER_FOLDED: {
485 if (prod == Teuchos::YAML::PROD_BSCALAR_HEADER_LITERAL) {
494 case Teuchos::YAML::PROD_DESCAPE: {
501 case Teuchos::YAML::PROD_SESCAPE: {
508 case Teuchos::YAML::PROD_OTHER_FIRST:
509 case Teuchos::YAML::PROD_SPACE_PLUS_FIRST: {
514 case Teuchos::YAML::PROD_SCALAR_TAIL_SPACE:
515 case Teuchos::YAML::PROD_SCALAR_TAIL_OTHER:
516 case Teuchos::YAML::PROD_DESCAPED_DQUOTED:
517 case Teuchos::YAML::PROD_DQUOTED_COMMON:
518 case Teuchos::YAML::PROD_SQUOTED_COMMON:
519 case Teuchos::YAML::PROD_ANY_COMMON:
520 case Teuchos::YAML::PROD_COMMON_SPACE:
521 case Teuchos::YAML::PROD_COMMON_OTHER:
522 case Teuchos::YAML::PROD_BSCALAR_HEAD_OTHER: {
523 swap(result_any, rhs.at(0));
527 case Teuchos::YAML::PROD_DQUOTED_NEXT:
528 case Teuchos::YAML::PROD_SQUOTED_NEXT:
529 case Teuchos::YAML::PROD_ANY_NEXT:
530 case Teuchos::YAML::PROD_SCALAR_TAIL_NEXT:
531 case Teuchos::YAML::PROD_SPACE_STAR_NEXT:
532 case Teuchos::YAML::PROD_SPACE_PLUS_NEXT:
533 case Teuchos::YAML::PROD_BSCALAR_HEAD_NEXT: {
535 "leading characters in " << prod <<
": any was empty\n");
536 swap(result_any, rhs.at(0));
541 case Teuchos::YAML::PROD_DQUOTED_EMPTY:
542 case Teuchos::YAML::PROD_SQUOTED_EMPTY:
543 case Teuchos::YAML::PROD_ANY_EMPTY:
544 case Teuchos::YAML::PROD_DESCAPE_EMPTY:
545 case Teuchos::YAML::PROD_SESCAPE_EMPTY:
546 case Teuchos::YAML::PROD_SCALAR_TAIL_EMPTY:
547 case Teuchos::YAML::PROD_SPACE_STAR_EMPTY:
548 case Teuchos::YAML::PROD_BSCALAR_HEAD_EMPTY: {
549 result_any = std::string();
552 case Teuchos::YAML::PROD_DESCAPED_DQUOT:
553 case Teuchos::YAML::PROD_SQUOTED_DQUOT:
554 case Teuchos::YAML::PROD_ANY_DQUOT: {
558 case Teuchos::YAML::PROD_DESCAPED_SLASH:
559 case Teuchos::YAML::PROD_SQUOTED_SLASH:
560 case Teuchos::YAML::PROD_ANY_SLASH: {
564 case Teuchos::YAML::PROD_SCALAR_TAIL_SQUOT:
565 case Teuchos::YAML::PROD_DQUOTED_SQUOT:
566 case Teuchos::YAML::PROD_ANY_SQUOT: {
570 case Teuchos::YAML::PROD_COMMON_COLON: {
574 case Teuchos::YAML::PROD_SCALAR_TAIL_DOT:
575 case Teuchos::YAML::PROD_COMMON_DOT: {
579 case Teuchos::YAML::PROD_SCALAR_TAIL_DASH:
580 case Teuchos::YAML::PROD_COMMON_DASH:
581 case Teuchos::YAML::PROD_BSCALAR_HEAD_DASH: {
585 case Teuchos::YAML::PROD_COMMON_PIPE: {
589 case Teuchos::YAML::PROD_COMMON_LSQUARE: {
593 case Teuchos::YAML::PROD_COMMON_RSQUARE: {
597 case Teuchos::YAML::PROD_COMMON_LCURLY: {
601 case Teuchos::YAML::PROD_COMMON_RCURLY: {
605 case Teuchos::YAML::PROD_COMMON_RANGLE: {
609 case Teuchos::YAML::PROD_COMMON_COMMA: {
613 case Teuchos::YAML::PROD_COMMON_PERCENT: {
617 case Teuchos::YAML::PROD_COMMON_EXCL: {
623 void map_first_item(any& result_any, any& first_item) {
627 safe_set_entry(list, pair.key, pair.value);
629 void map_next_item(any& result_any, any& items, any& next_item) {
631 swap(result_any, items);
634 safe_set_entry(list, pair.key, pair.value);
636 void map_item(any& result_any, any& key_any, any& value_any,
int scalar_type = -1) {
641 swap(result.key, key);
643 resolve_map_value(value_any, scalar_type);
644 if (value_any.type() ==
typeid(
bool)) {
646 result.value = ParameterEntry(value);
647 }
else if (value_any.type() ==
typeid(
int)) {
649 result.value = ParameterEntry(value);
650 }
else if (value_any.type() ==
typeid(
long long)) {
652 result.value = ParameterEntry(value);
653 }
else if (value_any.type() ==
typeid(
double)) {
655 result.value = ParameterEntry(value);
656 }
else if (value_any.type() ==
typeid(std::string)) {
658 result.value = ParameterEntry(value);
659 }
else if (value_any.type() ==
typeid(Array<int>)) {
661 result.value = ParameterEntry(value);
662 }
else if (value_any.type() ==
typeid(Array<long long>)) {
664 result.value = ParameterEntry(value);
665 }
else if (value_any.type() ==
typeid(Array<double>)) {
667 result.value = ParameterEntry(value);
668 }
else if (value_any.type() ==
typeid(Array<std::string>)) {
670 result.value = ParameterEntry(value);
671 }
else if (value_any.type() ==
typeid(TwoDArray<int>)) {
673 result.value = ParameterEntry(value);
674 }
else if (value_any.type() ==
typeid(TwoDArray<long long>)) {
676 result.value = ParameterEntry(value);
677 }
else if (value_any.type() ==
typeid(TwoDArray<double>)) {
679 result.value = ParameterEntry(value);
680 }
else if (value_any.type() ==
typeid(TwoDArray<std::string>)) {
682 result.value = ParameterEntry(value);
683 }
else if (value_any.type() ==
typeid(ParameterList)) {
685 ParameterList& result_pl = result.value.setList();
686 swap(result_pl, value);
687 result_pl.setName(result.key);
689 std::string msg =
"unexpected YAML map value type ";
690 msg += value_any.type().name();
691 msg +=
" for key \"";
694 throw ParserFail(msg);
697 void resolve_map_value(any& value_any,
int scalar_type = -1)
const {
698 if (value_any.type() ==
typeid(Scalar)) {
700 if (scalar_type == -1) {
701 scalar_type = scalar_value.infer_type();
703 if (scalar_type == Scalar::BOOL) {
704 value_any = parse_as<bool>(scalar_value.text);
705 }
else if (scalar_type == Scalar::INT) {
706 value_any = parse_as<int>(scalar_value.text);
707 }
else if (scalar_type == Scalar::LONG_LONG) {
708 value_any = parse_as<long long>(scalar_value.text);
709 }
else if (scalar_type == Scalar::DOUBLE) {
710 value_any = parse_as<double>(scalar_value.text);
712 value_any = scalar_value.text;
714 }
else if (value_any.type() ==
typeid(Array<Scalar>)) {
716 if (scalar_type == -1) {
717 if (scalars.size() == 0) {
718 throw ParserFail(
"implicitly typed arrays can't be empty\n"
719 "(need to determine their element type)\n");
723 scalar_type = Scalar::INT;
724 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
725 scalar_type = std::min(scalar_type, scalars[i].infer_type());
728 if (scalar_type == Scalar::INT) {
729 Array<int> result(scalars.size());
730 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
731 result[i] = parse_as<int>(scalars[i].text);
734 }
else if (scalar_type == Scalar::LONG_LONG) {
735 Array<long long> result(scalars.size());
736 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
737 result[i] = parse_as<long long>(scalars[i].text);
740 }
else if (scalar_type == Scalar::DOUBLE) {
741 Array<double> result(scalars.size());
742 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
743 result[i] = parse_as<double>(scalars[i].text);
746 }
else if (scalar_type == Scalar::STRING) {
747 Array<std::string> result(scalars.size());
748 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
749 result[i] = scalars[i].text;
753 }
else if (value_any.type() ==
typeid(Array<Array<Scalar>>)) {
755 if (scalar_type == -1) {
756 if (scalars.size() == 0) {
757 throw ParserFail(
"implicitly typed 2D arrays can't be empty\n"
758 "(need to determine their element type)\n");
762 scalar_type = Scalar::INT;
763 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
764 if (scalars[0].size() == 0) {
765 throw ParserFail(
"implicitly typed 2D arrays can't have empty rows\n"
766 "(need to determine their element type)\n");
768 if (scalars[i].size() != scalars[0].size()) {
769 throw ParserFail(
"2D array: sub-arrays are different sizes");
771 for (Teuchos_Ordinal j = 0; j < scalars[i].size(); ++j) {
772 int item_type = scalars[i][j].infer_type();
773 scalar_type = std::min(scalar_type, item_type);
777 if (scalar_type == Scalar::INT) {
778 TwoDArray<int> result(scalars.size(), scalars[0].size());
779 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
780 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
781 result(i, j) = parse_as<int>(scalars[i][j].text);
785 }
else if (scalar_type == Scalar::LONG_LONG) {
786 TwoDArray<long long> result(scalars.size(), scalars[0].size());
787 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
788 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
789 result(i, j) = parse_as<long long>(scalars[i][j].text);
793 }
else if (scalar_type == Scalar::DOUBLE) {
794 TwoDArray<double> result(scalars.size(), scalars[0].size());
795 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
796 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
797 result(i, j) = parse_as<double>(scalars[i][j].text);
801 }
else if (scalar_type == Scalar::STRING) {
802 TwoDArray<std::string> result(scalars.size(), scalars[0].size());
803 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
804 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
805 result(i, j) = scalars[i][j].text;
812 int interpret_tag(any& tag_any) {
813 if (tag_any.type() !=
typeid(std::string))
return -1;
815 if (text.find(
"bool") != std::string::npos)
return Scalar::BOOL;
816 else if (text.find(
"int") != std::string::npos)
return Scalar::INT;
817 else if (text.find(
"double") != std::string::npos)
return Scalar::DOUBLE;
818 else if (text.find(
"string") != std::string::npos)
return Scalar::STRING;
820 std::string msg =
"Unable to parse type tag \"";
823 throw ParserFail(msg);
826 void seq_first_item(any& result_any, any& first_any) {
828 if (first_any.type() ==
typeid(Scalar)) {
831 a.push_back(Scalar());
833 }
else if (first_any.type() ==
typeid(Array<Scalar>)) {
836 a.push_back(Array<Scalar>());
839 throw Teuchos::ParserFail(
840 "bug in YAMLParameterList::Reader: unexpected type for first sequence item");
843 void seq_next_item(any& result_any, any& items, any& next_item) {
845 swap(result_any, items);
846 if (result_any.type() ==
typeid(Array<Scalar>)) {
849 a.push_back(Scalar());
851 }
else if (result_any.type() ==
typeid(Array<Array<Scalar>>)) {
854 a.push_back(Array<Scalar>());
857 throw Teuchos::ParserFail(
858 "bug in YAMLParameterList::Reader: unexpected type for next sequence item");
862 void handle_block_scalar(
863 std::size_t parent_indent_level,
864 std::string
const& header,
865 std::string
const& leading_empties_or_comments,
866 std::string
const& rest,
867 std::string& content,
868 std::string& comment) {
871 char chomping_indicator;
872 std::size_t indentation_indicator = 0;
874 std::stringstream ss(header.substr(1,std::string::npos));
875 if (header.size() > 1 && my_isdigit(header[1])) {
876 ss >> indentation_indicator;
878 indentation_indicator += parent_indent_level;
880 if (!(ss >> chomping_indicator)) chomping_indicator =
'\0';
883 std::size_t first_newline = leading_empties_or_comments.find_first_of(
"\r\n");
885 if (first_newline > 0 && leading_empties_or_comments[first_newline - 1] ==
'\r') {
890 std::size_t keep_beg = first_newline + 1 - newline.size();
891 if (leading_empties_or_comments[0] ==
'#') {
892 comment = leading_empties_or_comments.substr(1, keep_beg);
895 std::size_t content_beg = leading_empties_or_comments.find_first_not_of(
"\r\n ");
896 if (content_beg == std::string::npos) content_beg = leading_empties_or_comments.size();
897 std::size_t newline_before_content = leading_empties_or_comments.rfind(
"\n", content_beg);
898 std::size_t num_indent_spaces = (content_beg - newline_before_content) - 1;
901 if (indentation_indicator > 0) {
904 "Indentation indicator " << indentation_indicator <<
" > leading spaces " << num_indent_spaces);
905 num_indent_spaces = indentation_indicator;
908 content = leading_empties_or_comments.substr(keep_beg, std::string::npos);
917 auto last_newline = content.find_last_of(
"\n", content.size() - 2);
918 if (last_newline == std::string::npos)
break;
919 std::size_t num_spaces = 0;
920 for (
auto ispace = last_newline + 1;
921 ispace < content.size() && content[ispace] ==
' ';
925 if (num_spaces >= num_indent_spaces)
break;
926 content.erase(content.begin() + last_newline + 1, content.end());
929 std::size_t unindent_pos = 0;
931 std::size_t next_newline = content.find_first_of(
"\n", unindent_pos);
932 if (next_newline == std::string::npos)
break;
933 std::size_t start_cut = next_newline + 1;
935 if (style ==
'>') start_cut -= newline.size();
936 std::size_t end_cut = next_newline + 1;
939 while (end_cut < content.size() && content[end_cut] ==
' ') {
943 end_cut = std::min(next_newline + 1 + num_indent_spaces, end_cut);
945 content = content.substr(0, start_cut) +
946 content.substr(end_cut, std::string::npos);
947 unindent_pos = start_cut;
949 if (chomping_indicator !=
'+') {
950 content = remove_trailing_whitespace_and_newlines(content);
951 if (chomping_indicator !=
'-') content += newline;
955 content = content.substr(newline.size(), std::string::npos);
969 if (paramList->name() ==
"ANONYMOUS") {
970 paramList->setName(updated->name());
973 paramList->setParameters(*updated);
976void updateParametersFromYamlCString(
const char*
const data,
983 if (paramList->name() ==
"ANONYMOUS") {
984 paramList->setName(updated->name());
986 paramList->setParameters(*updated);
990 paramList->setParametersNotAlreadySet(*updated);
997 const std::string&
name)
1002 if (paramList->name() ==
"ANONYMOUS") {
1003 paramList->setName(updated->name());
1005 paramList->setParameters(*updated);
1009 paramList->setParametersNotAlreadySet(*updated);
1015 return YAMLParameterList::parseYamlFile(yamlFileName);
1020 std::stringstream ss(yamlStr);
1021 return YAMLParameterList::parseYamlStream(ss);
1026 std::ostream &yamlOut
1029 YAMLParameterList::writeYamlStream(yamlOut, paramList);
1034 const std::string &yamlFileName
1037 YAMLParameterList::writeYamlFile(yamlFileName, paramList);
1040std::string convertXmlToYaml(
const std::string& xmlFileName)
1045 std::string yamlFileName;
1046 if(xmlFileName.find(
".xml") == std::string::npos)
1048 yamlFileName = xmlFileName +
".yaml";
1052 yamlFileName = xmlFileName.substr(0, xmlFileName.length() - 4) +
".yaml";
1054 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
1055 return yamlFileName;
1058void convertXmlToYaml(
const std::string& xmlFileName,
const std::string& yamlFileName)
1061 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
1064void convertXmlToYaml(std::istream& xmlStream, std::ostream& yamlStream)
1067 std::istreambuf_iterator<char> begin(xmlStream);
1068 std::istreambuf_iterator<char> end;
1069 std::string xmlString(begin, end);
1071 YAMLParameterList::writeYamlStream(yamlStream, *toConvert);
1074namespace YAMLParameterList
1077Teuchos::RCP<Teuchos::ParameterList> parseYamlText(
const std::string& text,
const std::string& name)
1079 Teuchos::YAMLParameterList::Reader reader;
1086Teuchos::RCP<Teuchos::ParameterList> parseYamlFile(
const std::string& yamlFile)
1088 Teuchos::YAMLParameterList::Reader reader;
1095Teuchos::RCP<Teuchos::ParameterList> parseYamlStream(std::istream& yaml)
1097 Teuchos::YAMLParameterList::Reader reader;
1099 reader.
read_stream(result, yaml,
"parseYamlStream");
1104void writeYamlStream(std::ostream& yaml,
const Teuchos::ParameterList& pl)
1107 std::ios_base::fmtflags flags = yaml.flags();
1109 std::ostringstream testStream;
1110 testStream.flags(flags);
1112 testStream << testVal;
1113 bool popFlags =
false;
1114 if(testStream.str() ==
"1")
1120 std::cout <<
"Warning: yaml stream format flags would confuse double with integer value with int.\n";
1121 std::cout <<
"Setting std::ios::showpoint on the stream to fix this (will restore flags when done)\n";
1122 std::ios_base::fmtflags flagsCopy = flags;
1123 flagsCopy |= std::ios::showpoint;
1126 yaml <<
"%YAML 1.1\n---\n";
1127 yaml << pl.
name() <<
':';
1134 writeParameterList(pl, yaml, 2);
1144void writeYamlFile(
const std::string& yamlFile,
const Teuchos::ParameterList& pl)
1146 std::ofstream yaml(yamlFile.c_str());
1153 yaml << std::scientific << std::setprecision(17);
1154 writeYamlStream(yaml, pl);
1157void writeParameterList(
const Teuchos::ParameterList& pl, std::ostream& yaml,
int indentLevel)
1166 for(PLIter it = pl.
begin(); it != pl.
end(); it++)
1168 writeParameter(pl.
name(it), pl.
entry(it), yaml, indentLevel);
1173template <
typename T>
1175 static void write(T
const& x, std::ostream& stream) {
1181struct YamlWrite<double> {
1182 static void write(
double const& x, std::ostream& stream) {
1183 generalWriteDouble(x, stream);
1188struct YamlWrite<std::string> {
1189 static void write(std::string
const& x, std::ostream& stream) {
1190 generalWriteString(x, stream);
1194template <
typename T>
1195void writeYamlTwoDArray(Teuchos::TwoDArray<T>
const& arr, std::ostream& stream)
1201 if (i) stream <<
", ";
1205 if (j) stream <<
", ";
1206 YamlWrite<T>::write(arr(i, j), stream);
1213void writeParameter(
const std::string& paramName,
const Teuchos::ParameterEntry& entry, std::ostream& yaml,
int indentLevel)
1215 for(
int i = 0; i < indentLevel; i++)
1219 generalWriteString(paramName, yaml);
1229 if(entry.
isType<Teuchos::Array<int> >())
1232 for(
int i = 0; i < arr.
size(); i++)
1235 if(i != arr.size() - 1)
1239 if(entry.
isType<Teuchos::Array<long long> >())
1242 for(
int i = 0; i < arr.
size(); i++)
1245 if(i != arr.size() - 1)
1249 else if(entry.
isType<Teuchos::Array<double> >())
1252 for(
int i = 0; i < arr.
size(); i++)
1254 generalWriteDouble(arr[i], yaml);
1255 if(i != arr.
size() - 1)
1259 else if(entry.
isType<Teuchos::Array<std::string> >())
1262 for(
int i = 0; i < arr.
size(); i++)
1264 generalWriteString(arr[i], yaml);
1265 if(i != arr.
size() - 1)
1273 if(entry.
isType<Teuchos::TwoDArray<int> >())
1275 writeYamlTwoDArray<int>(
1278 if(entry.
isType<Teuchos::TwoDArray<long long> >())
1280 writeYamlTwoDArray<long long>(
1283 else if(entry.
isType<Teuchos::TwoDArray<double> >())
1285 writeYamlTwoDArray<double>(
1288 else if(entry.
isType<Teuchos::TwoDArray<std::string> >())
1290 writeYamlTwoDArray<std::string>(
1294 else if(entry.
isType<
int>())
1296 yaml << Teuchos::getValue<int>(entry);
1298 else if(entry.
isType<
long long>())
1300 yaml << Teuchos::getValue<long long>(entry);
1302 else if(entry.
isType<
double>())
1306 else if(entry.
isType<std::string>())
1309 if(strchr(str.c_str(),
'\n'))
1315 std::size_t first_non_newline_pos = str.find_first_not_of(
"\r\n");
1316 if (first_non_newline_pos != std::string::npos &&
1317 str[first_non_newline_pos] ==
' ') {
1320 if (str[str.size() - 1] !=
'\n') yaml <<
"-";
1326 size_t next = str.find(
'\n', index);
1327 for(
int i = 0; i < indentLevel + 2; i++)
1331 if(next == std::string::npos)
1333 yaml << str.substr(index, std::string::npos);
1338 yaml << str.substr(index, next - index) <<
'\n';
1345 generalWriteString(str, yaml);
1348 else if(entry.
isType<
bool>())
1350 yaml << (Teuchos::getValue<bool>(entry) ?
"true" :
"false");
1355void generalWriteString(
const std::string& str, std::ostream& yaml)
1358 if(stringNeedsQuotes(str))
1361 for (std::size_t i = 0; i < str.size(); ++i) {
1362 if (str[i] ==
'\'') yaml <<
"''";
1363 else yaml << str[i];
1373void generalWriteDouble(
double d, std::ostream& yaml)
1378static bool containsSpecialCharacters(std::string
const& s) {
1379 char const*
const control_chars =
":'{}[],&*#?|<>=!%@\\";
1380 return s.find_first_of(control_chars) != std::string::npos;
1383bool stringNeedsQuotes(
const std::string& s)
1386 containsSpecialCharacters(s) ||
1387 is_parseable_as<bool>(s) ||
1388 is_parseable_as<int>(s) ||
1389 is_parseable_as<long long>(s) ||
1390 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.
T & getValue(const ParameterEntry &entry)
A templated helper function for returning the value of type T held in the ParameterEntry object,...
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.
const std::string & name() const
The name of this ParameterList.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT void updateParametersFromYamlFile(const std::string &yamlFileName, const Ptr< ParameterList > ¶mList)
Reads Yaml parameters from a file and updates those already in the given parameter list.
ParameterList()=default
Constructor.
ConstIterator begin() const
An iterator pointing to the first entry.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT RCP< ParameterList > getParametersFromYamlString(const std::string &yamlStr)
Reads Yaml parameters from a std::string and return them in a new parameter list.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT RCP< ParameterList > getParametersFromXmlString(const std::string &xmlStr)
Reads XML parameters from a std::string and return them in a new parameter list.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT void updateParametersFromYamlString(const std::string &yamlStr, const Ptr< ParameterList > ¶mList, bool overwrite, const std::string &name="")
Reads Yaml parameters from a std::string and updates those already in the given parameter list.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT void writeParameterListToYamlOStream(const ParameterList ¶mList, std::ostream &yamlOut)
Write parameters and sublists in Yaml format to an std::ostream.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT void writeParameterListToYamlFile(const ParameterList ¶mList, const std::string &yamlFileName)
Write parameters and sublist to an Yaml file.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT RCP< ParameterList > getParametersFromXmlFile(const std::string &xmlFileName)
Reads XML parameters from a file and return them in a new parameter list.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT RCP< ParameterList > getParametersFromYamlFile(const std::string &yamlFileName)
Reads Yaml parameters from a file and return them in a new parameter list.
Tries to create LALR(1) parser tables for a given grammar.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
Smart reference counting pointer class for automatic garbage collection.
void read_file(any &result, std::string const &file_name)
A convenience method for reading a file.
void read_string(any &result, std::string const &string, std::string const &string_name)
A convenience method for reading a string.
void read_stream(any &result, std::istream &stream, std::string const &stream_name_in)
The main method for reading a stream of text.
size_type getNumCols() const
returns the number of columns in the TwoDArray.
size_type getNumRows() const
returns the number of rows in the TwoDArray.
ValueType & any_cast(any &operand)
Used to extract the templated value held in Teuchos::any to a given value type.
ValueType & any_ref_cast(any &operand)
Keep the convenient behavior of Teuchos::any_cast w.r.t. references, but don't confuse it with the be...
T & make_any_ref(any &rhs)
Default constructs a new T value and returns a reference to it.
#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.