Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stack Of Tasks
dynamic-graph
Commits
7a687378
Commit
7a687378
authored
Feb 26, 2020
by
Joseph Mirabel
Browse files
Remove SignalCaster and related class.
parent
7041c7d6
Changes
8
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
7a687378
...
...
@@ -74,6 +74,7 @@ SET(${PROJECT_NAME}_HEADERS
include/
${
CUSTOM_HEADER_DIR
}
/signal.t.cpp
include/
${
CUSTOM_HEADER_DIR
}
/time-dependency.h
include/
${
CUSTOM_HEADER_DIR
}
/time-dependency.t.cpp
# Kept for a brittle backward compatiblity.
include/
${
CUSTOM_HEADER_DIR
}
/signal-caster.h
include/
${
CUSTOM_HEADER_DIR
}
/signal-cast-helper.h
include/
${
CUSTOM_HEADER_DIR
}
/all-signals.h
...
...
@@ -117,8 +118,6 @@ SET(${PROJECT_NAME}_SOURCES
src/mt/process-list.cpp
src/signal/signal-array.cpp
src/signal/signal-caster.cpp
src/signal/signal-cast-helper.cpp
src/command/value.cpp
src/command/command.cpp
...
...
include/dynamic-graph/fwd.hh
View file @
7a687378
...
...
@@ -23,14 +23,9 @@ class OutStringStream;
class
PluginLoader
;
class
PoolStorage
;
class
SignalCaster
;
class
SignalCastRegisterer
;
class
Tracer
;
class
TracerRealTime
;
template
<
typename
T
>
class
DefaultCastRegisterer
;
template
<
typename
T
,
typename
Time
>
class
Signal
;
template
<
typename
Time
>
class
SignalArray
;
...
...
include/dynamic-graph/signal-cast-helper.h
View file @
7a687378
...
...
@@ -5,175 +5,7 @@
#ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
#define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
#include <map>
#include <typeinfo>
#include <vector>
#include <boost/any.hpp>
#include <boost/format.hpp>
#include <boost/function/function1.hpp>
#include <boost/function/function2.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tuple/tuple.hpp>
#include <dynamic-graph/eigen-io.h>
#include "dynamic-graph/exception-signal.h"
#include "dynamic-graph/signal-caster.h"
#include <dynamic-graph/dynamic-graph-api.h>
namespace
dynamicgraph
{
/* --- NON GENERIC CASTER ------------------------------------------------- */
/// This class can be used to register default casts, i.e. casts
/// already supported by the object to an std::iostream through the
/// operators >> and << .
template
<
typename
T
>
class
DefaultCastRegisterer
:
public
SignalCastRegisterer
{
public:
DefaultCastRegisterer
()
:
SignalCastRegisterer
(
typeid
(
T
),
cast
)
{}
static
boost
::
any
cast
(
std
::
istringstream
&
iss
);
};
/// A default version of the caster, to serialize directly from
/// std::in.
template
<
typename
T
>
boost
::
any
DefaultCastRegisterer
<
T
>::
cast
(
std
::
istringstream
&
iss
)
{
T
inst
;
iss
>>
inst
;
if
(
iss
.
fail
())
{
boost
::
format
fmt
(
"failed to serialize %s "
);
fmt
%
iss
.
str
();
throw
ExceptionSignal
(
ExceptionSignal
::
GENERIC
,
fmt
.
str
());
}
return
inst
;
}
/* --- GENERIC CASTER ----------------------------------------------------- */
/*!
* This class is only used to group together static functions who differ by
* a template parameter. It is never actually instanced
* (the private constructor
* makes sure of that).
* Typical use of this class is to add the caster in the dg graph:
* dynamicgraph::SignalCastRegisterer sotCastRegisterer_TYPE
* (typeid(TYPE),
* SignalCast<TYPE>::disp_,
* SignalCast<TYPE>::cast_,
* SignalCast<TYPE>::trace_);
* NMSD: I don't really understand the use of this additional class. IMHO
* (comme on dit), it should be possible to rewrite the same-spec macros
* using specialization of the template class DefaultCastRegisterer. No?
*/
template
<
class
T
>
class
SignalCast
{
public:
static
T
cast
(
std
::
istringstream
&
)
{
throw
1
;
}
public:
// adapter functions for SignalCast
static
boost
::
any
cast_
(
std
::
istringstream
&
stringValue
)
{
return
boost
::
any_cast
<
T
>
(
cast
(
stringValue
));
}
private:
SignalCast
()
{}
};
}
// namespace dynamicgraph
/* -------------------------------------------------------------------------- */
/* --- MACROS --------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Declaration macro: one instance of each class needs to be present in
* order for casts to be registered.
*/
#define DG_SIGNAL_CAST_DECLARATION(TYPE) \
::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##TYPE( \
typeid(TYPE), SignalCast<TYPE>::disp_, SignalCast<TYPE>::cast_, \
SignalCast<TYPE>::trace_)
#define DG_SIGNAL_CAST_DECLARATION_NAMED(TYPE, NAME) \
::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##NAME( \
typeid(TYPE), SignalCast<TYPE>::disp_, SignalCast<TYPE>::cast_, \
SignalCast<TYPE>::trace_)
/* Standard definition macros: the three functions can be specified
* in the macros. To define then in the cpp, just put ';' in the args.
*/
#define DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, CAST, DISP, TRACE) \
template <> class SignalCast<TYPE> { \
public: \
static TYPE cast(std::istringstream &iss) CAST \
static void disp(TYPE const &t, std::ostream &os) DISP \
static void trace(TYPE const &t, std::ostream &os) TRACE public \
: static boost::any cast_(std::istringstream &stringValue) { \
return boost::any_cast<TYPE>(cast(stringValue)); \
} \
static void disp_(const boost::any &t, std::ostream &os) { \
disp(boost::any_cast<TYPE>(t), os); \
} \
static void trace_(const boost::any &t, std::ostream &os) { \
trace(boost::any_cast<TYPE>(t), os); \
} \
}
/* Standard definition macros: the functions <cast> and <disp> have
* to be implemented in the cpp files. The function <trace> is
* implemented as a proxy on <disp>.
*/
#define DG_SIGNAL_CAST_DEFINITION_HPP(TYPE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, ;, ;, { disp(t, os); })
/* Lazy definition: <cast> and <disp> are to proxys on the standard
* std input (>>) and output (<<). The function <trace> has to be
* implemented in the cpp.
*/
#define DG_SIGNAL_CAST_DEFINITION_TRACE_HPP(TYPE, TRACE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
{ \
TYPE res; \
iss >> res; \
return res; \
}, \
{ os << t << std::endl; }, TRACE)
/* Lazy lazy definition: the three functions are implemented as
* proxys on std::io operation.
*/
#define DG_SIGNAL_CAST_DEFINITION(TYPE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
{ \
TYPE res; \
iss >> res; \
return res; \
}, \
{ os << t << std::endl; }, { disp(t, os); })
/* Lazy definition of <cast> and <disp> with implementation of
* <trace> in the cpp.
*/
#define DG_SIGNAL_CAST_DEFINITION_TRACE(TYPE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
{ \
TYPE res; \
iss >> res; \
return res; \
}, \
{ os << t << std::endl; }, \
;)
/* Macro to add the define SignalCast in the dg graph. Typical use is:
* DG_ADD_CASTER( Matrix,matrix )
*/
#define DG_ADD_CASTER(TYPE, ID) \
::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##ID( \
typeid(TYPE), SignalCast<TYPE>::disp_, SignalCast<TYPE>::cast_, \
SignalCast<TYPE>::trace_)
#pragma warning "This file is now useless"
#endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
include/dynamic-graph/signal-caster.h
View file @
7a687378
...
...
@@ -5,15 +5,10 @@
#ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HH
#define DYNAMIC_GRAPH_SIGNAL_CASTER_HH
#include <map>
#include <typeinfo>
#include <vector>
#include <boost/any.hpp>
#include <boost/format.hpp>
#include <boost/function/function1.hpp>
#include <boost/function/function2.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tuple/tuple.hpp>
#include "dynamic-graph/exception-signal.h"
#include <dynamic-graph/dynamic-graph-api.h>
...
...
@@ -21,74 +16,6 @@
#include <dynamic-graph/eigen-io.h>
namespace
dynamicgraph
{
/// This singleton class allows serialization of a number of objects into
/// (disp) and from (cast) std i/o streams.
///
/// The transformation is done at run-time, i.e. SignalCaster
/// doesn't know about the type of objects it casts to.
///
/// It also allows registering of user-defined casts. A cast is
/// identified by the compiler. The mapping from a type to a
/// serialization function is dynamic, hence it is more complex than
/// a typical template-based compile-time resolve. So disp, cast and
/// trace are costly functions and should be used as such.
class
DYNAMIC_GRAPH_DLLAPI
SignalCaster
{
public:
virtual
~
SignalCaster
();
/// Destroy the unique instance.
static
void
destroy
();
/// Typedef of displayer functions that take an encapsulated 'any'
/// object and displays, cast, or trace it on an output stream
/// (serialization).
typedef
boost
::
function1
<
boost
::
any
,
std
::
istringstream
&>
caster_type
;
/// Get a reference to the unique object of the class.
static
SignalCaster
*
getInstance
(
void
);
/// Casts an object using a registered cast function.
boost
::
any
cast
(
const
std
::
type_info
&
,
std
::
istringstream
&
iss
);
/// Registers a cast.
void
registerCast
(
const
std
::
type_info
&
type
,
caster_type
caster
);
/// Unregister a cast.
void
unregisterCast
(
const
std
::
type_info
&
type
);
/// Checks if there is a displayer registered with type_name.
bool
existsCast
(
const
std
::
type_info
&
type
)
const
;
/// Return the list of type names registered.
std
::
vector
<
std
::
string
>
listTypenames
()
const
;
private:
/// Container for the three cast functions.
typedef
boost
::
tuple
<
caster_type
>
cast_functions_type
;
/// \brief Retrieve cast structure from its name.
cast_functions_type
&
getCast
(
const
std
::
string
&
type_name
);
/// This map associates the typename of objects and the corresponding
/// using boost::function with 'compatible' syntax
std
::
map
<
std
::
string
,
cast_functions_type
>
functions_
;
std
::
map
<
std
::
string
,
const
std
::
type_info
*>
type_info_
;
private:
explicit
SignalCaster
();
/// Pointer to the unique instance of the class.
static
SignalCaster
*
instance_
;
};
/// The SignalCast registerer class. Can be used to automatically
/// register a cast when instanced somewhere in a cpp file. Pass the
/// typeid () of the type you want to register a cast to as the first
/// argument. The code is provided here so the class does not need
/// to be exported.
class
DYNAMIC_GRAPH_DLLAPI
SignalCastRegisterer
{
public:
inline
SignalCastRegisterer
(
const
std
::
type_info
&
type
,
SignalCaster
::
caster_type
caster
)
{
SignalCaster
::
getInstance
()
->
registerCast
(
type
,
caster
);
}
};
/// Template class used to serialize a signal value.
template
<
typename
T
>
struct
signal_disp
{
inline
static
void
run
(
const
T
&
value
,
std
::
ostream
&
os
)
{
os
<<
value
<<
'\n'
;
}
...
...
src/signal/signal-cast-helper.cpp
deleted
100644 → 0
View file @
7041c7d6
// -*- c++-mode -*-
// Copyright 2010 François Bleibel
// Thomas Moulard,
// Olivier Stasse,
// Nicolas Mansard
//
#include <algorithm>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/lambda/bind.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal-cast-helper.h>
#include <dynamic-graph/signal-caster.h>
#include <exception>
#include <sstream>
#include <string>
namespace
dynamicgraph
{
// Define a custom implementation of the DefaultCastRegisterer
// 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
<
>
inline
boost
::
any
DefaultCastRegisterer
<
double
>::
cast
(
std
::
istringstream
&
iss
)
{
std
::
string
tmp
;
iss
>>
tmp
;
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
());
}
}
// for std::string, do not check failure. If input stream contains an
// empty string, iss.fail() returns true and an exception is thrown
template
<
>
inline
boost
::
any
DefaultCastRegisterer
<
std
::
string
>::
cast
(
std
::
istringstream
&
iss
)
{
std
::
string
inst
(
iss
.
str
());
return
inst
;
}
/// Registers useful casts
namespace
{
DefaultCastRegisterer
<
double
>
double_reg
;
DefaultCastRegisterer
<
int
>
int_reg
;
DefaultCastRegisterer
<
unsigned
int
>
uint_reg
;
DefaultCastRegisterer
<
bool
>
bool_reg
;
DefaultCastRegisterer
<
dynamicgraph
::
Vector
>
vectorCastRegisterer
;
DefaultCastRegisterer
<
dynamicgraph
::
Matrix
>
matrixCastRegisterer
;
DefaultCastRegisterer
<
boost
::
posix_time
::
ptime
>
ptimeCastRegisterer
;
DefaultCastRegisterer
<
std
::
string
>
stringCastRegisterer
;
}
// end of anonymous namespace.
}
// namespace dynamicgraph
src/signal/signal-caster.cpp
deleted
100644 → 0
View file @
7041c7d6
// -*- c++-mode -*-
// Copyright 2010 François Bleibel
// Thomas Moulard,
// Olivier Stasse
//
#include <algorithm>
#include <boost/lambda/bind.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal-caster.h>
#include <exception>
#include <sstream>
#include <string>
#include <dynamic-graph/linear-algebra.h>
namespace
dynamicgraph
{
SignalCaster
::
SignalCaster
()
{}
SignalCaster
::~
SignalCaster
()
{}
void
SignalCaster
::
destroy
()
{
delete
instance_
;
instance_
=
0
;
}
void
SignalCaster
::
registerCast
(
const
std
::
type_info
&
type
,
SignalCaster
::
caster_type
caster
)
{
if
(
existsCast
(
type
))
{
// If type name has already been registered for same type, do not throw.
if
(
type_info_
[
type
.
name
()]
!=
&
type
)
{
std
::
string
typeName
(
type
.
name
());
std
::
ostringstream
os
;
os
<<
"cast already registered for typename "
<<
typeName
<<
"
\n
"
<<
"and types differ: "
<<
&
type
<<
" != "
<<
type_info_
[
type
.
name
()]
<<
".
\n
"
<<
"A possible reason is that the dynamic"
<<
" library defining this type
\n
"
<<
"has been loaded several times, defining different symbols"
<<
" for the same type."
;
throw
ExceptionSignal
(
ExceptionSignal
::
GENERIC
,
os
.
str
());
}
}
functions_
[
type
.
name
()]
=
cast_functions_type
(
caster
);
type_info_
[
type
.
name
()]
=
&
type
;
}
void
SignalCaster
::
unregisterCast
(
const
std
::
type_info
&
type
)
{
size_t
n
=
functions_
.
erase
(
type
.
name
());
if
(
0
==
n
)
// erase did not find element
// TODO: throw Cast not registered exception
throw
ExceptionSignal
(
ExceptionSignal
::
GENERIC
);
}
bool
SignalCaster
::
existsCast
(
const
std
::
type_info
&
type
)
const
{
return
functions_
.
find
(
type
.
name
())
!=
functions_
.
end
();
}
SignalCaster
::
cast_functions_type
&
SignalCaster
::
getCast
(
const
std
::
string
&
type_name
)
{
std
::
map
<
std
::
string
,
cast_functions_type
>::
iterator
it
=
functions_
.
find
(
type_name
);
if
(
it
==
functions_
.
end
())
// TODO: throw "cast not registered" exception
throw
ExceptionSignal
(
ExceptionSignal
::
BAD_CAST
,
"Cast not registered"
);
return
it
->
second
;
}
std
::
vector
<
std
::
string
>
SignalCaster
::
listTypenames
()
const
{
std
::
vector
<
std
::
string
>
typeList
;
for
(
std
::
map
<
std
::
string
,
cast_functions_type
>::
const_iterator
iter
=
functions_
.
begin
();
iter
!=
functions_
.
end
();
++
iter
)
typeList
.
push_back
(
iter
->
first
);
return
typeList
;
}
boost
::
any
SignalCaster
::
cast
(
const
std
::
type_info
&
type
,
std
::
istringstream
&
iss
)
{
return
getCast
(
type
.
name
()).
get
<
0
>
()(
iss
);
}
/// Singleton on the library-wide instance of SignalCaster
SignalCaster
*
SignalCaster
::
getInstance
(
void
)
{
if
(
instance_
==
0
)
{
instance_
=
new
SignalCaster
;
}
return
instance_
;
}
SignalCaster
*
SignalCaster
::
instance_
=
0
;
}
// namespace dynamicgraph
tests/signal-all.cpp
View file @
7a687378
...
...
@@ -7,7 +7,7 @@
#include <dynamic-graph/debug.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/signal-array.h>
#include <dynamic-graph/signal-cast
-help
er.h>
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/tracer.h>
#include <assert.h>
...
...
@@ -140,21 +140,15 @@ BOOST_AUTO_TEST_CASE(test_base) {
}
BOOST_AUTO_TEST_CASE
(
test_cast_helper
)
{
DefaultCastRegisterer
<
int
>
defaultCR
;
std
::
istringstream
iss
;
iss
.
str
(
"1"
);
defaultCR
.
cast
(
iss
);
signal_cast
<
int
>::
run
(
iss
);
bool
res
=
false
;
try
{
{
std
::
istringstream
iss_fail
;
iss
.
str
(
"test"
);
defaultCR
.
cast
(
iss_fail
);
}
catch
(
ExceptionSignal
&
e
)
{
// Take int, not string
res
=
true
;
BOOST_CHECK_THROW
(
signal_cast
<
int
>::
run
(
iss_fail
),
ExceptionSignal
);
}
BOOST_CHECK
(
res
);
/// Test cast register with Vector
output_test_stream
output
;
...
...
@@ -164,15 +158,7 @@ BOOST_AUTO_TEST_CASE(test_cast_helper) {
avec
[
1
]
=
2.0
;
avec
[
2
]
=
3.0
;
avec
[
3
]
=
4.0
;
res
=
true
;
try
{
signal_trace
<
Vector
>::
run
(
avec
,
output
);
}
catch
(
ExceptionSignal
&
e
)
{
/// Exception in case of wrong cast.
/// This should not happen.
res
=
false
;
}
BOOST_CHECK
(
res
);
BOOST_CHECK_NO_THROW
(
signal_trace
<
Vector
>::
run
(
avec
,
output
));
/// Test cast register with Matrix
dynamicgraph
::
Matrix
amatrix
;
...
...
@@ -181,53 +167,8 @@ BOOST_AUTO_TEST_CASE(test_cast_helper) {
amatrix
(
0
,
1
)
=
1.0
;
amatrix
(
1
,
0
)
=
2.0
;
amatrix
(
1
,
1
)
=
3.0
;
res
=
true
;
try
{
signal_trace
<
Matrix
>::
run
(
amatrix
,
output
);
}
catch
(
ExceptionSignal
&
e
)
{
/// Exception in case of wrong cast.
/// This should happen
res
=
false
;
}
BOOST_CHECK
(
res
);
BOOST_CHECK_NO_THROW
(
signal_trace
<
Matrix
>::
run
(
amatrix
,
output
));
std
::
istringstream
aiss
(
"test"
);
DefaultCastRegisterer
<
std
::
string
>
defaultSR
;
boost
::
any
aTest
=
defaultSR
.
cast
(
aiss
);
}
BOOST_AUTO_TEST_CASE
(
signal_caster_basics
)
{
/// Get the singleton on registered types.
SignalCaster
*
asig_caster
=
SignalCaster
::
getInstance
();
/// List the registered types.
std
::
vector
<
std
::
string
>
amap
=
asig_caster
->
listTypenames
();
for
(
std
::
vector
<
std
::
string
>::
iterator
it
=
amap
.
begin
();
it
!=
amap
.
end
();
++
it
)
std
::
cout
<<
"signal_caster:listTypename: "
<<
*
it
<<
std
::
endl
;
/// Unregister a type
asig_caster
->
unregisterCast
(
typeid
(
double
));
/// Unregister the type a second time to generate exception
bool
res
=
false
;
try
{
asig_caster
->
unregisterCast
(
typeid
(
double
));
}
catch
(
ExceptionSignal
&
aes
)
{
res
=
(
aes
.
getCode
()
==
ExceptionSignal
::
GENERIC
);
}
BOOST_CHECK
(
res
);
/// Get the type cast to generate exception
res
=
false
;
double
ad
=
2.0
;
output_test_stream
output
;
try
{
signal_disp
<
double
>::
run
(
ad
,
output
);
}
catch
(
ExceptionSignal
&
aes
)
{
res
=
(
aes
.
getCode
()
==
ExceptionSignal
::
BAD_CAST
);
}
BOOST_CHECK
(
res
);
asig_caster
->
destroy
();
BOOST_CHECK
(
true
);
signal_cast
<
std
::
string
>::
run
(
aiss
);
}
tests/signal-cast-registerer.cpp
View file @
7a687378
...
...
@@ -13,8 +13,6 @@
#include <dynamic-graph/factory.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/signal-cast-helper.h>
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal.h>
#include "signal-cast-registerer-libA.hh"
...
...
@@ -31,40 +29,6 @@ using boost::test_tools::output_test_stream;
typedef
Eigen
::
VectorXd
Vector
;
typedef
Eigen
::
MatrixXd
Matrix
;
struct
EigenCastRegisterer_V
:
public
dynamicgraph
::
SignalCastRegisterer
{
typedef
Vector
bnuVector
;
EigenCastRegisterer_V
()
:
SignalCastRegisterer
(
typeid
(
bnuVector
),
castVector
)
{}
static
boost
::
any
castVector
(
std
::
istringstream
&
iss
)
{
bnuVector
res
;
iss
>>
res
;
return
res
;
}
};
template
<
typename
Derived
>
struct
EigenCastRegisterer_M
:
public
dynamicgraph
::
SignalCastRegisterer
{
typedef
Matrix
bnuMatrix
;
EigenCastRegisterer_M
()
:
SignalCastRegisterer
(
typeid
(
bnuMatrix
),
castMatrix
)
{}
static
boost
::
any
castMatrix
(
std
::
istringstream
&
iss
)
{
bnuMatrix
res
;
iss
>>
res
;