25 #include <boost/optional.hpp>
26 #include <boost/property_tree/ptree.hpp>
27 #include <boost/property_tree/xml_parser.hpp>
28 #include <boost/property_tree/exceptions.hpp>
37 using boost::optional;
42 bool PTreeComparison::CompareRootValues(ptree
const& pt1, ptree
const& pt2,
double acceptable_diff)
44 std::string pt1_value = pt1.get_value<std::string>();
45 std::string pt2_value = pt2.get_value<std::string>();
47 if (acceptable_diff > 1.0e-15) {
48 bool pt1_value_is_number =
false;
49 bool pt2_value_is_number =
false;
51 double pt1_value_parsed = 0.0;
52 double pt2_value_parsed = 0.0;
55 pt1_value_parsed = pt1.get_value<
double>();
56 pt1_value_is_number =
true;
57 }
catch (ptree_bad_data &) {
58 pt1_value_is_number =
false;
62 pt2_value_parsed = pt2.get_value<
double>();
63 pt2_value_is_number =
true;
64 }
catch (ptree_bad_data &) {
65 pt2_value_is_number =
false;
68 if (pt1_value_is_number && pt2_value_is_number) {
69 if (pt1_value.find(
'.') == std::string::npos
70 && pt2_value.find(
'.') == std::string::npos) {
72 return pt1_value == pt2_value;
74 double const diff = fabs(pt2_value_parsed - pt1_value_parsed)
75 / (1.0 + fabs(pt1_value_parsed));
76 bool equal = (diff < acceptable_diff);
78 cout <<
"LeafTransformer::CompareRootValues> Diff too large: " << diff << endl;
85 return pt1_value == pt2_value;
88 bool PTreeComparison::CompareArray(ptree
const& pt1, ptree
const& pt2,
double acceptable_diff)
91 if (!CompareRootValues(pt1, pt2, acceptable_diff)) {
92 cout <<
"LeafTransformer::CompareArray> Root values not equal" << endl;
96 if (pt1.size() != pt2.size()) {
97 cout <<
"LeafTransformer::CompareArray> Different number of children." << endl;
101 auto pt1_child_entry = pt1.begin();
102 auto pt2_child_entry = pt2.begin();
103 while (pt1_child_entry != pt1.end() && pt2_child_entry != pt2.end()) {
104 if (pt1_child_entry->first != pt2_child_entry->first) {
105 cout <<
"LeafTransformer::CompareArray> Array elements have different keys." << endl;
109 if (pt1_child_entry->first.rfind(
"_array") == pt1_child_entry->first.length()-6) {
110 if (!CompareArray(pt1_child_entry->second, pt2_child_entry->second, acceptable_diff)) {
114 if (!CompareNonArray(pt1_child_entry->second, pt2_child_entry->second, acceptable_diff)) {
115 cout <<
"LeafTransformer::CompareNonArray> Subtree: " << pt1_child_entry->first << endl;
126 bool PTreeComparison::CompareNonArray(ptree
const& pt1, ptree
const& pt2,
double acceptable_diff)
129 if (!CompareRootValues(pt1, pt2, acceptable_diff)) {
130 cout <<
"LeafTransformer::CompareNonArray> Root values not equal" << endl;
134 if (pt1.size() != pt2.size()) {
135 cout <<
"LeafTransformer::CompareNonArray> Different number of children." << endl;
139 for (
auto const& pt1_child_entry : pt1) {
140 ptree
const & pt1_child = pt1_child_entry.second;
141 optional<ptree const&> pt2_child = pt2.get_child_optional(pt1_child_entry.first);
144 cout <<
"LeafTransformer::CompareNonArray> Child doesn't exist: " << pt1_child_entry.first
149 if (pt1_child_entry.first.rfind(
"_array") == pt1_child_entry.first.length()-6) {
150 if (!CompareArray(pt1_child, *pt2_child, acceptable_diff)) {
154 if (!CompareNonArray(pt1_child, *pt2_child, acceptable_diff)) {
155 cout <<
"LeafTransformer::CompareNonArray> Subtree: " << pt1_child_entry.first << endl;
Namespace for miscellaneous utilities.
Namespace for SimPT shell package.
Interface for PTreeComparison.
String manipulation utilities.
Header file for Exception class.