Commit 7041c7d6 authored by Joseph Mirabel's avatar Joseph Mirabel
Browse files

Make signal_cast template

parent 6fe68723
......@@ -18,6 +18,7 @@
#include "dynamic-graph/exception-signal.h"
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/eigen-io.h>
namespace dynamicgraph {
/// This singleton class allows serialization of a number of objects into
......@@ -109,9 +110,56 @@ template <> struct signal_disp<std::string> {
inline static void run (const std::string &value, std::ostream &os) { os << value; }
};
template <typename T> T signal_cast(std::istringstream &iss) {
return boost::any_cast<T>(SignalCaster::getInstance()->cast(typeid(T), iss));
/// Template class used to deserialize a signal value (reverse of signal_disp).
template <typename T> struct signal_cast {
inline static T run (std::istringstream &iss) {
T inst;
iss >> inst;
if (iss.fail()) {
throw ExceptionSignal(ExceptionSignal::GENERIC,
"failed to serialize " + iss.str());
}
return inst;
}
};
/// Template specialization of signal_cast for std::string.
template <> struct signal_cast<std::string> {
inline static std::string run (std::istringstream &iss) { return iss.str(); }
};
/// Template specialization of signal_cast for double
/// to workaround the limitations of the stream based approach.
///
/// When dealing with double: displaying a double on a stream
/// is *NOT* the opposite of reading a double from a stream.
///
/// In practice, it means that there is no way to read
/// a NaN, +inf, -inf from a stream!
///
/// To workaround this problem, parse special values manually
/// (the strings used are the one produces by displaying special
/// values on a stream).
template <> struct signal_cast<double> {
inline static double run (std::istringstream &iss) {
std::string tmp (iss.str());
if (tmp == "nan")
return std::numeric_limits<double>::quiet_NaN();
else if (tmp == "inf" || tmp == "+inf")
return std::numeric_limits<double>::infinity();
else if (tmp == "-inf")
return -1. * std::numeric_limits<double>::infinity();
try {
return boost::lexical_cast<double>(tmp);
} catch (boost::bad_lexical_cast &) {
boost::format fmt("failed to serialize %s (to double)");
fmt % tmp;
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
}
};
/// Template class used to display a signal value.
template <typename T> struct signal_trace {
......
......@@ -30,7 +30,7 @@ Signal<T, Time>::Signal(std::string name)
template <class T, class Time>
void Signal<T, Time>::set(std::istringstream &stringValue) {
(*this) = signal_cast<T>(stringValue);
(*this) = signal_cast<T>::run(stringValue);
}
template <class T, class Time>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment