17 #include <unordered_map>
18 #include <unordered_set>
21 #include <dynamic_reconfigure/BoolParameter.h>
22 #include <dynamic_reconfigure/Config.h>
23 #include <dynamic_reconfigure/DoubleParameter.h>
24 #include <dynamic_reconfigure/IntParameter.h>
25 #include <dynamic_reconfigure/StrParameter.h>
54 ::std::list<::std::string>* errors =
nullptr)
61 inline bool convert(const ::XmlRpc::XmlRpcValue& x,
bool& v,
bool =
false,
62 ::std::list<::std::string>* errors =
nullptr)
72 const auto i =
static_cast<int>(x);
75 v =
static_cast<bool>(i);
78 else if (errors !=
nullptr)
79 errors->push_back(::
cras::format(
"Cannot convert int value %i to boolean.", i));
82 if (errors !=
nullptr)
87 inline bool convert(const ::XmlRpc::XmlRpcValue& x,
int& v,
bool =
false,
88 ::std::list<::std::string>* errors =
nullptr)
96 if (errors !=
nullptr)
102 #define DEFINE_INTEGRAL_CONVERT(resultType, xmlType, minBound, maxBound) \
104 inline bool convert(const ::XmlRpc::XmlRpcValue& x, resultType& v, bool skipNonConvertible = false, \
105 ::std::list<::std::string>* errors = nullptr) \
108 if (!convert(x, i, skipNonConvertible, errors)) \
110 if (i < (minBound) || i > (maxBound)) { \
111 if (errors != nullptr) \
112 errors->push_back(::cras::format("Value %s is out of bounds <%s, %s>.", \
113 ::cras::to_string(i).c_str(), ::cras::to_string(minBound).c_str(), ::cras::to_string(maxBound).c_str())); \
116 v = static_cast<resultType>(i); \
133 inline
bool convert(const ::
XmlRpc::XmlRpcValue& x,
double& v,
bool = false,
134 ::
std::list<::
std::
string>* errors =
nullptr)
144 v =
static_cast<double>(
static_cast<int>(x));
148 if (errors !=
nullptr)
154 #define DEFINE_DOUBLE_CONVERT(resultType, xmlType, minBound, maxBound) \
156 inline bool convert(const ::XmlRpc::XmlRpcValue& x, resultType& v, bool skipNonConvertible = false, \
157 ::std::list<::std::string>* errors = nullptr) \
160 if (!convert(x, i, skipNonConvertible, errors)) \
162 if (::std::isnan(i)) { v = ::std::numeric_limits<resultType>::quiet_NaN(); return true; } \
163 if (::std::isinf(i) && i > 0) { v = ::std::numeric_limits<resultType>::infinity(); return true; } \
164 if (::std::isinf(i) && i < 0) { v = -::std::numeric_limits<resultType>::infinity(); return true; } \
165 if (i < (minBound) || i > (maxBound)) { \
166 if (errors != nullptr) \
167 errors->push_back(::cras::format("Value %s is out of bounds <%s, %s>.", \
168 ::cras::to_string(i).c_str(), ::cras::to_string(minBound).c_str(), ::cras::to_string(maxBound).c_str())); \
171 v = static_cast<resultType>(i); \
178 inline bool convert(const ::XmlRpc::XmlRpcValue& x, std::string& v,
bool =
false,
180 ::std::list<::std::string>* errors =
nullptr)
184 v =
static_cast<::std::string
>(x);
188 if (errors !=
nullptr)
197 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::map<::std::string, T>& v,
198 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
202 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::unordered_map<::std::string, T>& v,
203 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
207 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::vector<T>& v,
208 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
212 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::list<T>& v,
213 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
217 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::set<T>& v,
218 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
222 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::unordered_set<T>& v,
223 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
226 template<
typename T,
size_t N>
227 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::array<T, N>& v,
228 bool skipNonConvertible =
false, ::std::list<::std::string>* errors =
nullptr);
230 #define DEFINE_ARRAY_CONVERT(arrayType, insertFn) \
231 template<typename T> \
232 inline bool convert(const ::XmlRpc::XmlRpcValue& x, arrayType<T>& v, bool skipNonConvertible, \
233 ::std::list<::std::string>* errors) \
235 if (x.getType() != ::XmlRpc::XmlRpcValue::TypeArray) { \
236 if (errors != nullptr) \
237 errors->push_back(::cras::format("Cannot convert type %s to array.", ::cras::to_cstring(x.getType())));\
241 for (size_t i = 0; i < x.size(); ++i) \
244 if (convert(x[i], t, skipNonConvertible, errors)) \
246 else if (!skipNonConvertible) \
249 return v.size() > 0 || x.size() == 0; \
257 template<
typename T,
size_t N>
258 inline bool convert(const ::XmlRpc::XmlRpcValue& x, ::std::array<T, N>& v,
bool skipNonConvertible,
259 ::std::list<::std::string>* errors)
263 if (errors !=
nullptr)
269 if (errors !=
nullptr)
270 errors->push_back(::
cras::format(
"The array is expected to have %i items, but %i was given.", N, x.size()));
273 for (
size_t i = 0; i < x.size(); ++i)
276 if (
convert(x[i],
t, skipNonConvertible, errors))
284 #define DEFINE_STRUCT_CONVERT(mapType) \
285 template<typename T> \
286 inline bool convert(const ::XmlRpc::XmlRpcValue& x, mapType<::std::string, T>& v, bool skipNonConvertible, \
287 ::std::list<::std::string>* errors) \
289 if (x.getType() != ::XmlRpc::XmlRpcValue::TypeStruct) { \
290 if (errors != nullptr) \
291 errors->push_back(::cras::format("Cannot convert type %s to struct.", ::cras::to_cstring(x.getType())));\
295 for (auto it = x.begin(); it != x.end(); ++it) \
298 if (convert(it->second, t, skipNonConvertible, errors)) \
300 else if (!skipNonConvertible) \
303 return v.size() > 0 || x.size() == 0; \
309 inline
bool convert(const ::
XmlRpc::XmlRpcValue& x, ::dynamic_reconfigure::Config& v,
bool skipNonConvertible,
310 ::
std::list<::
std::
string>* errors)
314 if (errors !=
nullptr)
316 "Cannot convert type %s to dynamic_reconfigure/Config.", ::
cras::to_cstring(x.getType())));
319 for (
auto it = x.begin(); it != x.end(); ++it)
321 const auto& name = it->first;
322 const auto& val = it->second;
323 switch (val.getType())
327 dynamic_reconfigure::BoolParameter p;
329 p.value =
static_cast<bool>(val);
330 v.bools.push_back(p);
335 dynamic_reconfigure::IntParameter p;
337 p.value =
static_cast<int>(val);
343 dynamic_reconfigure::DoubleParameter p;
345 p.value =
static_cast<double>(val);
346 v.doubles.push_back(p);
351 dynamic_reconfigure::StrParameter p;
353 p.value =
static_cast<std::string
>(val);
359 if (errors !=
nullptr)
360 errors->push_back(::
cras::format(
"Field %s of type %s cannot be stored in dynamic_reconfigure/Config.",
362 if (!skipNonConvertible)