Skip to content

Commit 590bb01

Browse files
committed
Simplify further serialization and deserialization of a signal.
1 parent 56971cf commit 590bb01

File tree

3 files changed

+79
-49
lines changed

3 files changed

+79
-49
lines changed

include/dynamic-graph/signal-caster.h

Lines changed: 71 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,91 @@
1616
#include <dynamic-graph/eigen-io.h>
1717

1818
namespace dynamicgraph {
19-
/// Template class used to serialize a signal value.
20-
template <typename T> struct signal_disp {
21-
inline static void run (const T &value, std::ostream &os) { os << value; }
19+
20+
/// Inherit from this class if you want to keep default implementation for some
21+
/// functions.
22+
template <typename T> struct signal_io_base {
23+
/// serialize a signal value.
24+
inline static void disp (const T &value, std::ostream &os) { os << value; }
25+
/// deserialize a signal value.
26+
inline static T cast (std::istringstream &is) {
27+
T inst;
28+
is >> inst;
29+
if (is.fail()) {
30+
throw ExceptionSignal(ExceptionSignal::GENERIC,
31+
"failed to serialize " + is.str());
32+
}
33+
return inst;
34+
}
35+
/// write a signal value to log file
36+
inline static void trace(const T &value, std::ostream &os) { os << value; }
2237
};
2338

39+
/// Inherit from this class if tracing is not implemented for a given type.
40+
template <typename T> struct signal_io_unimplemented {
41+
inline static void disp (const T &, std::ostream &) {
42+
throw std::logic_error("this disp is not implemented.");
43+
}
44+
inline static T cast (std::istringstream &) {
45+
throw std::logic_error("this cast is not implemented.");
46+
}
47+
inline static void trace(const T &, std::ostream &) {
48+
throw std::logic_error("this trace is not implemented.");
49+
}
50+
};
51+
52+
/// Class used for I/O operations in Signal<T,Time>
53+
template <typename T> struct signal_io : signal_io_base<T> {};
54+
2455
/// Template specialization of signal_disp for Eigen objects
2556
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
26-
struct signal_disp<Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > > {
27-
inline static void run(const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &value, std::ostream &os) {
57+
struct signal_io<Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > >
58+
: signal_io_base <Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > >
59+
{
60+
typedef Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > matrix_type;
61+
62+
inline static void disp(const matrix_type &value, std::ostream &os) {
2863
static const Eigen::IOFormat row_format (Eigen::StreamPrecision,
2964
Eigen::DontAlignCols, " ", " ", "", "", "", "");
3065
os << value.format(row_format);
3166
}
32-
};
3367

34-
/// Template specialization of signal_disp for std::string.
35-
/// Do not print '\n' at the end.
36-
template <> struct signal_disp<std::string> {
37-
inline static void run (const std::string &value, std::ostream &os) { os << value; }
68+
inline static void trace(const matrix_type &value, std::ostream &os) {
69+
static const Eigen::IOFormat row_format (Eigen::StreamPrecision,
70+
Eigen::DontAlignCols, "\t", "\t", "", "", "", "");
71+
os << value.format(row_format);
72+
}
3873
};
3974

40-
/// Template class used to deserialize a signal value (reverse of signal_disp).
41-
template <typename T> struct signal_cast {
42-
inline static T run (std::istringstream &iss) {
43-
T inst;
44-
iss >> inst;
45-
if (iss.fail()) {
46-
throw ExceptionSignal(ExceptionSignal::GENERIC,
47-
"failed to serialize " + iss.str());
48-
}
49-
return inst;
75+
/// Template specialization of signal_io for Eigen quaternion objects
76+
template<typename _Scalar, int _Options>
77+
struct signal_io<Eigen::Quaternion< _Scalar, _Options> >
78+
: signal_io_base<Eigen::Quaternion< _Scalar, _Options> >
79+
{
80+
typedef Eigen::Quaternion< _Scalar, _Options> quat_type;
81+
typedef Eigen::Matrix< _Scalar, 4, 1, _Options> matrix_type;
82+
83+
inline static void disp(const quat_type &value, std::ostream &os) {
84+
signal_io<matrix_type>::disp(value.coeffs(), os);
85+
}
86+
87+
inline static quat_type cast (std::istringstream &is) {
88+
return quat_type(signal_io<matrix_type>::cast(is));
89+
}
90+
91+
inline static void trace(const quat_type &value, std::ostream &os) {
92+
signal_io<matrix_type>::trace(value.coeffs(), os);
5093
}
5194
};
5295

53-
/// Template specialization of signal_cast for std::string.
54-
template <> struct signal_cast<std::string> {
55-
inline static std::string run (std::istringstream &iss) { return iss.str(); }
96+
/// Template specialization of signal_io for std::string.
97+
/// Do not print '\n' at the end.
98+
template <> struct signal_io<std::string> : signal_io_base<std::string>
99+
{
100+
inline static std::string cast (std::istringstream &iss) { return iss.str(); }
56101
};
57102

58-
/// Template specialization of signal_cast for double
103+
/// Template specialization of signal_io for double
59104
/// to workaround the limitations of the stream based approach.
60105
///
61106
/// When dealing with double: displaying a double on a stream
@@ -67,8 +112,8 @@ inline static std::string run (std::istringstream &iss) { return iss.str(); }
67112
/// To workaround this problem, parse special values manually
68113
/// (the strings used are the one produces by displaying special
69114
/// values on a stream).
70-
template <> struct signal_cast<double> {
71-
inline static double run (std::istringstream &iss) {
115+
template <> struct signal_io<double> : signal_io_base<double> {
116+
inline static double cast (std::istringstream &iss) {
72117
std::string tmp (iss.str());
73118

74119
if (tmp == "nan")
@@ -88,21 +133,6 @@ inline static double run (std::istringstream &iss) {
88133
}
89134
};
90135

91-
/// Template class used to display a signal value.
92-
template <typename T> struct signal_trace {
93-
inline static void run(const T &value, std::ostream &os) { os << value; }
94-
};
95-
96-
/// Template specialization of signal_trace for Eigen objects
97-
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
98-
struct signal_trace<Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {
99-
inline static void run(const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> &value, std::ostream &os) {
100-
static const Eigen::IOFormat row_format (Eigen::StreamPrecision,
101-
Eigen::DontAlignCols, "\t", "\t", "", "", "", "");
102-
os << value.format(row_format);
103-
}
104-
};
105-
106136
} // end of namespace dynamicgraph.
107137

108138
#endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH

include/dynamic-graph/signal.t.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@ 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>::run(stringValue);
33+
(*this) = signal_io<T>::cast(stringValue);
3434
}
3535

3636
template <class T, class Time>
3737
void Signal<T, Time>::get(std::ostream &os) const {
38-
signal_disp<T>::run(this->accessCopy(), os);
38+
signal_io<T>::disp(this->accessCopy(), os);
3939
}
4040

4141
template <class T, class Time>
4242
void Signal<T, Time>::trace(std::ostream &os) const {
4343
try {
44-
signal_trace<T>::run(this->accessCopy(), os);
44+
signal_io<T>::trace(this->accessCopy(), os);
4545
} catch DG_RETHROW catch (...) {
4646
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
4747
"TRACE operation not possible with this signal. ",

tests/signal-all.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ BOOST_AUTO_TEST_CASE(test_base) {
142142
BOOST_AUTO_TEST_CASE(test_cast_helper) {
143143
std::istringstream iss;
144144
iss.str("1");
145-
signal_cast<int>::run(iss);
145+
signal_io<int>::cast(iss);
146146

147147
{
148148
std::istringstream iss_fail;
149149
iss.str("test");
150-
BOOST_CHECK_THROW(signal_cast<int>::run(iss_fail), ExceptionSignal);
150+
BOOST_CHECK_THROW(signal_io<int>::cast(iss_fail), ExceptionSignal);
151151
}
152152

153153
/// Test cast register with Vector
@@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(test_cast_helper) {
158158
avec[1] = 2.0;
159159
avec[2] = 3.0;
160160
avec[3] = 4.0;
161-
BOOST_CHECK_NO_THROW(signal_trace<Vector>::run(avec, output));
161+
BOOST_CHECK_NO_THROW(signal_io<Vector>::trace(avec, output));
162162

163163
/// Test cast register with Matrix
164164
dynamicgraph::Matrix amatrix;
@@ -167,8 +167,8 @@ BOOST_AUTO_TEST_CASE(test_cast_helper) {
167167
amatrix(0, 1) = 1.0;
168168
amatrix(1, 0) = 2.0;
169169
amatrix(1, 1) = 3.0;
170-
BOOST_CHECK_NO_THROW(signal_trace<Matrix>::run(amatrix, output));
170+
BOOST_CHECK_NO_THROW(signal_io<Matrix>::trace(amatrix, output));
171171

172172
std::istringstream aiss("test");
173-
signal_cast<std::string>::run(aiss);
173+
signal_io<std::string>::cast(aiss);
174174
}

0 commit comments

Comments
 (0)