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  // ------------------------- VALUE RECONCILATION- ---------------------------
66 
67  // TODO: refactor common template code
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 = "") {
70 
71  // check for equality
72  if (val1 == val2) return val1;
73 
74  // resolve one value none
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;
78  }
79 
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("")));
81  }
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);
85  }
86 
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 = "") {
89 
90  // check for equality
91  if (val1 == val2) return val1;
92 
93  // resolve one value none
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;
97  }
98 
99  // resolve different numbers
100  if (resolve_max != boost::none) {
101  return *resolve_max ? std::max(*val1, *val2) : std::min(*val1, *val2);
102  }
103 
104  // throw std::runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", 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("")));
106  }
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);
110  }
111 
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 = "") {
114 
115  // check for equality
116  if (val1 == val2) return val1;
117 
118  // resolve one value none
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;
122  }
123 
124  // resolve different booleans
125  if (resolve_true != boost::none) {
126  return val1 == resolve_true ? val1 : val2; // if resolve true, return true, else return false
127  } else {
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("")));
129  }
130  }
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);
134  }
135 
136  template <class T>
137  std::vector<T> reconcile(const std::vector<T>& v1, const std::vector<T>& v2, const std::string& err_msg = "") {
138 
139  // check for equality
140  if (v1 == v2) return v1;
141 
142  // resolve one vector empty
143  if (v1.empty()) return v2;
144  if (v2.empty()) return v1;
145 
146  // otherwise cannot reconcile
147  throw std::runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? std::string(". ") + err_msg : std::string("")));
148  }
149 }
150 #endif /* gen_utils_h */
gen_utils
Definition: gen_utils.h:64