57 #include "include_base_utils.h"
58 #include "common/util.h"
68 template <class T, typename std::enable_if<std::is_same<T, std::string>::value, T>::type* =
nullptr>
69 boost::optional<T> reconcile(
const boost::optional<T>& val1,
const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max,
const std::string& err_msg =
"") {
72 if (val1 == val2)
return val1;
75 if (val1 == boost::none || val2 == boost::none) {
76 if (resolve_defined != boost::none && *resolve_defined ==
false)
return boost::none;
77 else return val1 == boost::none ? val2 : val1;
80 throw std::runtime_error(std::string(
"Cannot reconcile strings: ") + to_string(val1) + std::string(
" vs ") + to_string(val2) + (!err_msg.empty() ? std::string(
". ") + err_msg : std::string(
"")));
82 template <class T, typename std::enable_if<std::is_same<T, std::string>::value, T>::type* =
nullptr>
83 boost::optional<T> reconcile(
const boost::optional<T>& val1,
const boost::optional<T>& val2,
const std::string& err_msg =
"") {
84 return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
87 template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* =
nullptr>
88 boost::optional<T> reconcile(
const boost::optional<T>& val1,
const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max,
const std::string& err_msg =
"") {
91 if (val1 == val2)
return val1;
94 if (val1 == boost::none || val2 == boost::none) {
95 if (resolve_defined != boost::none && *resolve_defined ==
false)
return boost::none;
96 else return val1 == boost::none ? val2 : val1;
100 if (resolve_max != boost::none) {
101 return *resolve_max ? std::max(*val1, *val2) : std::min(*val1, *val2);
105 throw std::runtime_error(std::string(
"Cannot reconcile integrals: ") + to_string(val1) + std::string(
" vs ") + to_string(val2) + (!err_msg.empty() ? std::string(
". ") + err_msg : std::string(
"")));
107 template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* =
nullptr>
108 boost::optional<T> reconcile(
const boost::optional<T>& val1,
const boost::optional<T>& val2,
const std::string& err_msg =
"") {
109 return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
112 template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
113 boost::optional<T> reconcile(
const boost::optional<T>& val1,
const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max,
const std::string& err_msg =
"") {
116 if (val1 == val2)
return val1;
119 if (val1 == boost::none || val2 == boost::none) {
120 if (resolve_defined != boost::none && *resolve_defined ==
false)
return boost::none;
121 else return val1 == boost::none ? val2 : val1;
125 if (resolve_true != boost::none) {
126 return val1 == resolve_true ? val1 : val2;
128 throw std::runtime_error(std::string(
"Cannot reconcile booleans: ") + to_string(val1) + std::string(
" vs ") + to_string(val2) + (!err_msg.empty() ? std::string(
". ") + err_msg : std::string(
"")));
131 template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
132 boost::optional<T> reconcile(
const boost::optional<T>& val1,
const boost::optional<T>& val2,
const std::string& err_msg =
"") {
133 return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
137 std::vector<T> reconcile(
const std::vector<T>& v1,
const std::vector<T>& v2,
const std::string& err_msg =
"") {
140 if (v1 == v2)
return v1;
143 if (v1.empty())
return v2;
144 if (v2.empty())
return v1;
147 throw std::runtime_error(
"Cannot reconcile vectors" + (!err_msg.empty() ? std::string(
". ") + err_msg : std::string(
"")));