|
18 | 18 | #include "dynamic-graph/exception-signal.h"
|
19 | 19 | #include <dynamic-graph/dynamic-graph-api.h>
|
20 | 20 | #include <dynamic-graph/linear-algebra.h>
|
| 21 | +#include <dynamic-graph/eigen-io.h> |
21 | 22 |
|
22 | 23 | namespace dynamicgraph {
|
23 | 24 | /// This singleton class allows serialization of a number of objects into
|
@@ -109,9 +110,56 @@ template <> struct signal_disp<std::string> {
|
109 | 110 | inline static void run (const std::string &value, std::ostream &os) { os << value; }
|
110 | 111 | };
|
111 | 112 |
|
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; |
114 | 123 | }
|
| 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 | +}; |
115 | 163 |
|
116 | 164 | /// Template class used to display a signal value.
|
117 | 165 | template <typename T> struct signal_trace {
|
|
0 commit comments