dynamic-graph  4.1.0-8-gdab7-dirty
Dynamic graph library
signal-cast-helper.h
1 // -*- c++-mode -*-
2 // Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse,
3 // Nicolas Mansard
4 //
5 
6 #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
7 #define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
8 #include <map>
9 #include <typeinfo>
10 #include <vector>
11 
12 #include <boost/any.hpp>
13 #include <boost/format.hpp>
14 #include <boost/function/function1.hpp>
15 #include <boost/function/function2.hpp>
16 #include <boost/lexical_cast.hpp>
17 #include <boost/tuple/tuple.hpp>
18 
19 #include <dynamic-graph/eigen-io.h>
20 
21 #include "dynamic-graph/exception-signal.h"
22 #include "dynamic-graph/signal-caster.h"
23 #include <dynamic-graph/dynamic-graph-api.h>
24 
25 namespace dynamicgraph {
26 
27 /* --- NON GENERIC CASTER ------------------------------------------------- */
28 
32 template <typename T>
33 class DefaultCastRegisterer : public SignalCastRegisterer {
34 public:
35  DefaultCastRegisterer()
36  : SignalCastRegisterer(typeid(T), disp, cast, trace) {}
37 
38  static boost::any cast(std::istringstream &iss);
39 
40  static void disp(const boost::any &object, std::ostream &os) {
41  os << boost::any_cast<T>(object) << std::endl;
42  }
43 
44  static void trace(const boost::any &object, std::ostream &os) {
45  disp(object, os);
46  }
47 };
48 
51 template <typename T>
52 boost::any DefaultCastRegisterer<T>::cast(std::istringstream &iss) {
53  T inst;
54  iss >> inst;
55  if (iss.fail()) {
56  boost::format fmt("failed to serialize %s ");
57  fmt % iss.str();
58  throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
59  }
60  return inst;
61 }
62 
63 /* --- GENERIC CASTER ----------------------------------------------------- */
80 template <class T> class SignalCast {
81 public:
82  static T cast(std::istringstream &) { throw 1; }
83  static void disp(const T &, std::ostream &) { throw 1; }
84  static void trace(const T &t, std::ostream &os) { disp(t, os); }
85 
86 public:
87  // adapter functions for SignalCast
88  static boost::any cast_(std::istringstream &stringValue) {
89  return boost::any_cast<T>(cast(stringValue));
90  }
91  static void disp_(const boost::any &t, std::ostream &os) {
92  disp(boost::any_cast<T>(t), os);
93  }
94  static void trace_(const boost::any &t, std::ostream &os) {
95  trace(boost::any_cast<T>(t), os);
96  }
97 
98 private:
99  SignalCast() {}
100 };
101 
102 } // namespace dynamicgraph
103 
104 /* -------------------------------------------------------------------------- */
105 /* --- MACROS --------------------------------------------------------------- */
106 /* -------------------------------------------------------------------------- */
107 
108 /* Declaration macro: one instance of each class needs to be present in
109  * order for casts to be registered.
110  */
111 
112 #define DG_SIGNAL_CAST_DECLARATION(TYPE) \
113  ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##TYPE( \
114  typeid(TYPE), SignalCast<TYPE>::disp_, SignalCast<TYPE>::cast_, \
115  SignalCast<TYPE>::trace_)
116 
117 #define DG_SIGNAL_CAST_DECLARATION_NAMED(TYPE, NAME) \
118  ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##NAME( \
119  typeid(TYPE), SignalCast<TYPE>::disp_, SignalCast<TYPE>::cast_, \
120  SignalCast<TYPE>::trace_)
121 
122 /* Standard definition macros: the three functions can be specified
123  * in the macros. To define then in the cpp, just put ';' in the args.
124  */
125 #define DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, CAST, DISP, TRACE) \
126  template <> class SignalCast<TYPE> { \
127  public: \
128  static TYPE cast(std::istringstream &iss) CAST \
129  static void disp(TYPE const &t, std::ostream &os) DISP \
130  static void trace(TYPE const &t, std::ostream &os) TRACE public \
131  : static boost::any cast_(std::istringstream &stringValue) { \
132  return boost::any_cast<TYPE>(cast(stringValue)); \
133  } \
134  static void disp_(const boost::any &t, std::ostream &os) { \
135  disp(boost::any_cast<TYPE>(t), os); \
136  } \
137  static void trace_(const boost::any &t, std::ostream &os) { \
138  trace(boost::any_cast<TYPE>(t), os); \
139  } \
140  }
141 
142 /* Standard definition macros: the functions <cast> and <disp> have
143  * to be implemented in the cpp files. The function <trace> is
144  * implemented as a proxy on <disp>.
145  */
146 #define DG_SIGNAL_CAST_DEFINITION_HPP(TYPE) \
147  DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, ;, ;, { disp(t, os); })
148 
149 /* Lazy definition: <cast> and <disp> are to proxys on the standard
150  * std input (>>) and output (<<). The function <trace> has to be
151  * implemented in the cpp.
152  */
153 #define DG_SIGNAL_CAST_DEFINITION_TRACE_HPP(TYPE, TRACE) \
154  DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
155  { \
156  TYPE res; \
157  iss >> res; \
158  return res; \
159  }, \
160  { os << t << std::endl; }, TRACE)
161 
162 /* Lazy lazy definition: the three functions are implemented as
163  * proxys on std::io operation.
164  */
165 #define DG_SIGNAL_CAST_DEFINITION(TYPE) \
166  DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
167  { \
168  TYPE res; \
169  iss >> res; \
170  return res; \
171  }, \
172  { os << t << std::endl; }, { disp(t, os); })
173 
174 /* Lazy definition of <cast> and <disp> with implementation of
175  * <trace> in the cpp.
176  */
177 #define DG_SIGNAL_CAST_DEFINITION_TRACE(TYPE) \
178  DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
179  { \
180  TYPE res; \
181  iss >> res; \
182  return res; \
183  }, \
184  { os << t << std::endl; }, \
185  ;)
186 
187 /* Macro to add the define SignalCast in the dg graph. Typical use is:
188  * DG_ADD_CASTER( Matrix,matrix )
189  */
190 #define DG_ADD_CASTER(TYPE, ID) \
191  ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##ID( \
192  typeid(TYPE), SignalCast<TYPE>::disp_, SignalCast<TYPE>::cast_, \
193  SignalCast<TYPE>::trace_)
194 
195 #endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
Exceptions raised when an error related to signals happen.
static boost::any cast(std::istringstream &iss)