Monero C++ Library
gen_utils.h
1 
52 #pragma once
53 
54 #ifndef gen_utils_h
55 #define gen_utils_h
56 
57 #include "include_base_utils.h"
58 #include "common/util.h"
59 
63 namespace gen_utils
64 {
65  using namespace std;
66 
67  // ------------------------- VALUE RECONCILATION- ---------------------------
68 
69  // TODO: refactor common template code
70  template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
71  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 string& err_msg = "") {
72 
73  // check for equality
74  if (val1 == val2) return val1;
75 
76  // resolve one value none
77  if (val1 == boost::none || val2 == boost::none) {
78  if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
79  else return val1 == boost::none ? val2 : val1;
80  }
81 
82  throw runtime_error(string("Cannot reconcile strings: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
83  }
84  template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
85  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
86  return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
87  }
88 
89  template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
90  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 string& err_msg = "") {
91 
92  // check for equality
93  if (val1 == val2) return val1;
94 
95  // resolve one value none
96  if (val1 == boost::none || val2 == boost::none) {
97  if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
98  else return val1 == boost::none ? val2 : val1;
99  }
100 
101  // resolve different numbers
102  if (resolve_max != boost::none) {
103  return *resolve_max ? max(*val1, *val2) : min(*val1, *val2);
104  }
105 
106  // throw runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", val1, val2);
107  throw runtime_error(string("Cannot reconcile integrals: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
108  }
109  template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
110  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
111  return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
112  }
113 
114  template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
115  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 string& err_msg = "") {
116 
117  // check for equality
118  if (val1 == val2) return val1;
119 
120  // resolve one value none
121  if (val1 == boost::none || val2 == boost::none) {
122  if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
123  else return val1 == boost::none ? val2 : val1;
124  }
125 
126  // resolve different booleans
127  if (resolve_true != boost::none) {
128  return val1 == resolve_true ? val1 : val2; // if resolve true, return true, else return false
129  } else {
130  throw runtime_error(string("Cannot reconcile booleans: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
131  }
132  }
133  template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
134  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
135  return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
136  }
137 
138  template <class T>
139  vector<T> reconcile(const vector<T>& v1, const vector<T>& v2, const string& err_msg = "") {
140 
141  // check for equality
142  if (v1 == v2) return v1;
143 
144  // resolve one vector empty
145  if (v1.empty()) return v2;
146  if (v2.empty()) return v1;
147 
148  // otherwise cannot reconcile
149  throw runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? string(". ") + err_msg : string("")));
150  }
151 }
152 #endif /* gen_utils_h */
Definition: gen_utils.h:63