Skip to content
Snippets Groups Projects
Commit 9365d919 authored by Thomas Moulard's avatar Thomas Moulard
Browse files

Clean signal-caster.h.

parent 242f086a
No related branches found
No related tags found
No related merge requests found
...@@ -23,6 +23,13 @@ namespace dynamicgraph ...@@ -23,6 +23,13 @@ namespace dynamicgraph
class FactoryStorage; class FactoryStorage;
class EntityRegisterer; class EntityRegisterer;
class SignalCaster;
class SignalCastRegisterer;
template<typename T>
class DefaultCastRegisterer;
} // end of namespace dynamicgraph. } // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_FWD_HH #endif //! DYNAMIC_GRAPH_FWD_HH
/* // -*- c++-mode -*-
* Copyright 2010, // Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse
* François Bleibel, //
* Olivier Stasse, // This file is part of dynamic-graph.
* // dynamic-graph is free software: you can redistribute it and/or modify
* CNRS/AIST // 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
* This file is part of dynamic-graph. // (at your option) any later version.
* dynamic-graph is free software: you can redistribute it and/or //
* modify it under the terms of the GNU Lesser General Public License // dynamic-graph is distributed in the hope that it will be useful,
* as published by the Free Software Foundation, either version 3 of // but WITHOUT ANY WARRANTY; without even the implied warranty of
* the License, or (at your option) any later version. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* dynamic-graph is distributed in the hope that it will be // GNU Lesser General Public License for more details.
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty // You should have received a copy of the GNU Lesser General Public License
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // along with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HH
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>. # define DYNAMIC_GRAPH_SIGNAL_CASTER_HH
*/ # include <map>
# include <typeinfo>
#ifndef SIGNALCASTER_H_ # include <iostream>
#define SIGNALCASTER_H_
# include <boost/any.hpp>
#include <map> # include <boost/function/function1.hpp>
#include <typeinfo> # include <boost/function/function2.hpp>
#include <boost/function/function1.hpp> # include <boost/tuple/tuple.hpp>
#include <boost/function/function2.hpp>
#include <boost/any.hpp> # include <dynamic-graph/dynamic-graph-api.h>
#include <boost/tuple/tuple.hpp> # include "dynamic-graph/exception-signal.h"
#include <iostream>
namespace dynamicgraph
#include <dynamic-graph/dynamic-graph-api.h> {
#include "dynamic-graph/exception-signal.h" /// This class allows serialization of a number of objects into
/// (disp) and from (cast) std i/o streams.
namespace dynamicgraph { ///
/// The transformation is done at run-time, i.e. SignalCaster
/*! This class allows serialization of a number of objects into (disp) and from /// doesn't know about the type of objects it casts to.
* (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 /// It also allows registering of user-defined casts. A cast is
* user-defined casts. A cast is identified by the compiler /// identified by the compiler The mapping from a type to a
* The mapping from a type to a serialization function is dynamic, hence it is more /// serialization function is dynamic, hence it is more complex than
* complex than a typical template-based compile-time resolve. So disp, cast and /// a typical template-based compile-time resolve. So disp, cast and
* trace are costly functions and should be used as such. /// trace are costly functions and should be used as such.
*/ class DYNAMIC_GRAPH_DLLAPI SignalCaster
class DYNAMIC_GRAPH_DLLAPI SignalCaster { {
public: public:
SignalCaster(); explicit SignalCaster ();
virtual ~SignalCaster(); virtual ~SignalCaster ();
/*! Typedef of displayer functions that take an encapsulated 'any' object /// Typedef of displayer functions that take an encapsulated 'any'
* and displays, cast, or trace it on an output stream (serialization). /// object and displays, cast, or trace it on an output stream
*/ /// (serialization).
typedef boost::function2<void, const boost::any&, std::ostream&> displayer_type; typedef boost::function2<void, const boost::any&, std::ostream&>
typedef boost::function1<boost::any, std::istringstream&> caster_type; displayer_type;
typedef boost::function2<void, const boost::any&, std::ostream&> tracer_type; typedef boost::function1<boost::any, std::istringstream&> caster_type;
typedef boost::function2<void, const boost::any&, std::ostream&>
/// Displays an object using a registered displayer function tracer_type;
void disp(const boost::any& object, std::ostream& os);
/// Traces an object using a registered trace function /// Displays an object using a registered displayer function.
void trace(const boost::any& object, std::ostream& os); void disp (const boost::any& object, std::ostream& os);
/// Casts an object using a registered cast function /// Traces an object using a registered trace function.
boost::any cast(const std::type_info&, std::istringstream& iss); void trace (const boost::any& object, std::ostream& os);
/// Registers a cast /// Casts an object using a registered cast function.
void registerCast(const std::type_info& type, displayer_type displayer, boost::any cast (const std::type_info&, std::istringstream& iss);
caster_type caster, tracer_type tracer); /// Registers a cast.
/// Unregisters a cast void registerCast (const std::type_info& type, displayer_type displayer,
void unregisterCast(const std::type_info& type); caster_type caster, tracer_type tracer);
/// Checks if there is a displayer registered with type_name /// Unregister a cast.
bool existsCast(const std::type_info& type); void unregisterCast (const std::type_info& type);
private: /// Checks if there is a displayer registered with type_name.
/// Container for the three cast functions bool existsCast (const std::type_info& type);
typedef boost::tuple<displayer_type, caster_type, tracer_type> cast_functions_type;
/*! This map associates the typename of objects and the corresponding private:
* using boost::function with 'compatible' syntax /// Container for the three cast functions.
*/ typedef boost::tuple<displayer_type, caster_type, tracer_type>
std::map<std::string, cast_functions_type> functions_; cast_functions_type;
};
/// This map associates the typename of objects and the corresponding
/// using boost::function with 'compatible' syntax
/// The library-wide instance of SignalCaster std::map<std::string, cast_functions_type> functions_;
extern DYNAMIC_GRAPH_DLLAPI SignalCaster g_caster; };
/*! /// The library-wide instance of SignalCaster
* The SignalCast registerer class. Can be used to automatically register a cast when extern DYNAMIC_GRAPH_DLLAPI SignalCaster g_caster;
* instanced somewhere in a cpp file. Pass the typeid() of the type you want to
* register a cast to as the first argument. ///The SignalCast registerer class. Can be used to automatically
* The code is provided here so the class does not need to be exported. /// 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
class SignalCastRegisterer { /// argument. The code is provided here so the class does not need
public: /// to be exported.
inline SignalCastRegisterer(const std::type_info& type, SignalCaster::displayer_type displayer, class DYNAMIC_GRAPH_DLLAPI SignalCastRegisterer
SignalCaster::caster_type caster, SignalCaster::tracer_type tracer) { {
g_caster.registerCast(type, displayer, caster, tracer); public:
} inline SignalCastRegisterer (const std::type_info& type,
}; SignalCaster::displayer_type displayer,
SignalCaster::caster_type caster,
/*! This class can be used to register default casts, i.e. casts already supported by SignalCaster::tracer_type tracer)
* the object to an std::iostream through the operators >> and << . {
*/ g_caster.registerCast(type, displayer, caster, tracer);
template<typename T> class DefaultCastRegisterer : public SignalCastRegisterer { }
public: };
DefaultCastRegisterer() : SignalCastRegisterer(typeid(T), disp, cast, trace) {}
static boost::any cast(std::istringstream& iss) { T inst; iss >> inst; return inst; } /// This class can be used to register default casts, i.e. casts
static void disp(const boost::any& object, std::ostream& os) { os << boost::any_cast<T>(object) << std::endl;; } /// already supported by the object to an std::iostream through the
static void trace(const boost::any& object, std::ostream& os) { disp(object,os); } /// operators >> and << .
}; template<typename T>
class DefaultCastRegisterer : public SignalCastRegisterer
/*! {
* Global signal cast template (helper) functions public:
* DefaultCastRegisterer ()
* Using these avoid using the typeid() operator and keeps the implementation : SignalCastRegisterer (typeid(T), disp, cast, trace)
* details hidden. {}
*/
template<typename T> void signal_disp(const T& value, std::ostream& os) static boost::any cast(std::istringstream& iss)
{ g_caster.disp(value, os); } {
T inst;
template<typename T> T signal_cast(std::istringstream& iss) iss >> inst;
{ return inst;
return boost::any_cast<T>(g_caster.cast(typeid(T), iss)); }
}
static void disp(const boost::any& object, std::ostream& os)
template<typename T> void signal_trace(const T& value, std::ostream& os) {
{ g_caster.trace(value, os); } os << boost::any_cast<T> (object) << std::endl;
}
} // namespace dynamicgraph
static void trace (const boost::any& object, std::ostream& os)
#endif /* SIGNALCASTER_H_ */ {
disp(object,os);
}
};
/// Global signal cast template (helper) functions
///
/// Using these avoid using the typeid() operator and keeps the
/// implementation details hidden.
template<typename T>
void signal_disp (const T& value, std::ostream& os)
{
g_caster.disp(value, os);
}
template<typename T>
T signal_cast(std::istringstream& iss)
{
return boost::any_cast<T>(g_caster.cast(typeid(T), iss));
}
template<typename T>
void signal_trace (const T& value, std::ostream& os)
{
g_caster.trace(value, os);
}
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH
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