Skip to content

Commit 7041c7d

Browse files
committed
Make signal_cast template
1 parent 6fe6872 commit 7041c7d

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

include/dynamic-graph/signal-caster.h

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "dynamic-graph/exception-signal.h"
1919
#include <dynamic-graph/dynamic-graph-api.h>
2020
#include <dynamic-graph/linear-algebra.h>
21+
#include <dynamic-graph/eigen-io.h>
2122

2223
namespace dynamicgraph {
2324
/// This singleton class allows serialization of a number of objects into
@@ -109,9 +110,56 @@ template <> struct signal_disp<std::string> {
109110
inline static void run (const std::string &value, std::ostream &os) { os << value; }
110111
};
111112

112-
template <typename T> T signal_cast(std::istringstream &iss) {
113-
return boost::any_cast<T>(SignalCaster::getInstance()->cast(typeid(T), iss));
113+
/// Template class used to deserialize a signal value (reverse of signal_disp).
114+
template <typename T> struct signal_cast {
115+
inline static T run (std::istringstream &iss) {
116+
T inst;
117+
iss >> inst;
118+
if (iss.fail()) {
119+
throw ExceptionSignal(ExceptionSignal::GENERIC,
120+
"failed to serialize " + iss.str());
121+
}
122+
return inst;
114123
}
124+
};
125+
126+
/// Template specialization of signal_cast for std::string.
127+
template <> struct signal_cast<std::string> {
128+
inline static std::string run (std::istringstream &iss) { return iss.str(); }
129+
};
130+
131+
/// Template specialization of signal_cast for double
132+
/// to workaround the limitations of the stream based approach.
133+
///
134+
/// When dealing with double: displaying a double on a stream
135+
/// is *NOT* the opposite of reading a double from a stream.
136+
///
137+
/// In practice, it means that there is no way to read
138+
/// a NaN, +inf, -inf from a stream!
139+
///
140+
/// To workaround this problem, parse special values manually
141+
/// (the strings used are the one produces by displaying special
142+
/// values on a stream).
143+
template <> struct signal_cast<double> {
144+
inline static double run (std::istringstream &iss) {
145+
std::string tmp (iss.str());
146+
147+
if (tmp == "nan")
148+
return std::numeric_limits<double>::quiet_NaN();
149+
else if (tmp == "inf" || tmp == "+inf")
150+
return std::numeric_limits<double>::infinity();
151+
else if (tmp == "-inf")
152+
return -1. * std::numeric_limits<double>::infinity();
153+
154+
try {
155+
return boost::lexical_cast<double>(tmp);
156+
} catch (boost::bad_lexical_cast &) {
157+
boost::format fmt("failed to serialize %s (to double)");
158+
fmt % tmp;
159+
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
160+
}
161+
}
162+
};
115163

116164
/// Template class used to display a signal value.
117165
template <typename T> struct signal_trace {

include/dynamic-graph/signal.t.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Signal<T, Time>::Signal(std::string name)
3030

3131
template <class T, class Time>
3232
void Signal<T, Time>::set(std::istringstream &stringValue) {
33-
(*this) = signal_cast<T>(stringValue);
33+
(*this) = signal_cast<T>::run(stringValue);
3434
}
3535

3636
template <class T, class Time>

0 commit comments

Comments
 (0)