Skip to content
Snippets Groups Projects
Commit 3a3deb24 authored by Nicolas Mansard's avatar Nicolas Mansard
Browse files

IVIGIT: transfert some code and automatic-code-generation macros from sot-core to dg.

parent f4d187ef
No related branches found
No related tags found
No related merge requests found
......@@ -57,6 +57,7 @@ signal.t.cpp
time-dependency.h
time-dependency.t.cpp
signal-caster.h
signal-cast-helper.h
all-signals.h
tracer.h
......
// -*- c++-mode -*-
// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
# define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
# include <map>
# include <typeinfo>
# include <iostream>
# 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/dynamic-graph-api.h>
# include "dynamic-graph/exception-signal.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), disp, cast, trace)
{}
DYNAMIC_GRAPH_DLLEXPORT
static boost::any cast (std::istringstream& iss);
DYNAMIC_GRAPH_DLLEXPORT
static void disp (const boost::any& object, std::ostream& os)
{
os << boost::any_cast<T> (object) << std::endl;
}
DYNAMIC_GRAPH_DLLEXPORT
static void trace (const boost::any& object, std::ostream& os)
{
disp(object,os);
}
};
/// 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_);
*/
template< class T >
class SignalCast
{
public:
static T cast( std::istringstream& stringValue ) { throw 1;}
static void disp( const T& t,std::ostream& os ) { throw 1; }
static void trace( const T& t,std::ostream& os ) { disp(t,os); }
public:
// adapter functions for SignalCast
static boost::any cast_( std::istringstream& stringValue ) {
return boost::any_cast<T>(cast(stringValue));
}
static void disp_( const boost::any& t,std::ostream& os ) {
disp(boost::any_cast<T>(t), os);
}
static void trace_( const boost::any& t,std::ostream& os ) {
trace(boost::any_cast<T>(t),os);
}
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: \
DYNAMIC_GRAPH_DLLEXPORT \
static boost::any cast_( std::istringstream& stringValue ) { \
return boost::any_cast<TYPE>(cast(stringValue)); \
} \
DYNAMIC_GRAPH_DLLEXPORT \
static void disp_( const boost::any& t,std::ostream& os ) { \
disp(boost::any_cast<TYPE>(t), os); \
} \
DYNAMIC_GRAPH_DLLEXPORT \
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_)
#endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
......@@ -41,6 +41,7 @@ ADD_LIBRARY(${LIBRARY_NAME}
signal/signal-array.cpp
signal/signal-caster.cpp
signal/signal-cast-helper.cpp
command/value.cpp
command/command.cpp
......
// -*- c++-mode -*-
// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal-cast-helper.h>
#include <dynamic-graph/dynamic-graph-api.h>
#include <exception>
#include <boost/lambda/bind.hpp>
#include <string>
#include <sstream>
#include <algorithm>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/linear-algebra.h>
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 ());
}
}
/// Registers useful casts
namespace
{
DefaultCastRegisterer<double> double_reg;
DefaultCastRegisterer<int> int_reg;
DefaultCastRegisterer<unsigned int> uint_reg;
DefaultCastRegisterer<dynamicgraph::Vector> vectorCastRegisterer;
DefaultCastRegisterer<dynamicgraph::Matrix> matrixCastRegisterer;
} // end of anonymous namespace.
} // namespace dynamicgraph
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment