From fda270a922983fcd31fbc377a7e4d957a7e062b5 Mon Sep 17 00:00:00 2001 From: florent <florent@laas.fr> Date: Fri, 5 Nov 2010 20:56:43 +0100 Subject: [PATCH] Support more type for command parameters * include/dynamic-graph/command-setter.h, * include/dynamic-graph/command-setter.t.cpp, * include/dynamic-graph/value.h, * src/command/value.cpp: support bool, unsigned and float. --- include/dynamic-graph/command-setter.h | 1 - include/dynamic-graph/command-setter.t.cpp | 225 +++++++++++++++++++-- include/dynamic-graph/value.h | 14 +- src/command/value.cpp | 107 ++++++++-- 4 files changed, 309 insertions(+), 38 deletions(-) diff --git a/include/dynamic-graph/command-setter.h b/include/dynamic-graph/command-setter.h index 070b063..3d04e26 100644 --- a/include/dynamic-graph/command-setter.h +++ b/include/dynamic-graph/command-setter.h @@ -64,7 +64,6 @@ namespace dynamicgraph { virtual Value doExecute(); private: - static const std::vector<Value::Type> typeVector(); SetterMethod setterMethod_; }; } // namespace command diff --git a/include/dynamic-graph/command-setter.t.cpp b/include/dynamic-graph/command-setter.t.cpp index 9abd495..962dd8e 100644 --- a/include/dynamic-graph/command-setter.t.cpp +++ b/include/dynamic-graph/command-setter.t.cpp @@ -19,47 +19,228 @@ #define DYNAMIC_GRAPH_COMMAND_SETTER_T_CPP #include <sstream> +#include <boost/assign/list_of.hpp> namespace dynamicgraph { class Entity; namespace command { - template <class E, typename T> - const std::vector<Value::Type> Setter<E, T>::typeVector() + // + // Template specialization: bool + // + template <class E> + class Setter<E, bool> : public Command { + public: + /// Pointer to method that sets paramter of type bool + typedef void (E::*SetterMethod) (const bool&); + /// Constructor + Setter(E& entity, SetterMethod); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, bool>::Setter(E& entity, SetterMethod setterMethod) : + Command(entity, boost::assign::list_of(Value::BOOL)), + setterMethod_(setterMethod) + { + } + + template <class E> + Value Setter<E, bool>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + bool value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: unsigned + // + template <class E> + class Setter<E, unsigned> : public Command { + public: + /// Pointer to method that sets paramter of type unsigned + typedef void (E::*SetterMethod) (const unsigned&); + /// Constructor + Setter(E& entity, SetterMethod); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, unsigned>::Setter(E& entity, SetterMethod setterMethod) : + Command(entity, boost::assign::list_of(Value::UNSIGNED)), + setterMethod_(setterMethod) + { + } + + template <class E> + Value Setter<E, unsigned>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + unsigned value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: int + // + template <class E> + class Setter<E, int> : public Command { + public: + /// Pointer to method that sets paramter of type int + typedef void (E::*SetterMethod) (const int&); + /// Constructor + Setter(E& entity, SetterMethod); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, int>::Setter(E& entity, SetterMethod setterMethod) : + Command(entity, boost::assign::list_of(Value::INT)), + setterMethod_(setterMethod) + { + } + + template <class E> + Value Setter<E, int>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + int value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: float + // + template <class E> + class Setter<E, float> : public Command { + public: + /// Pointer to method that sets paramter of type float + typedef void (E::*SetterMethod) (const float&); + /// Constructor + Setter(E& entity, SetterMethod); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, float>::Setter(E& entity, SetterMethod setterMethod) : + Command(entity, boost::assign::list_of(Value::FLOAT)), + setterMethod_(setterMethod) + { + } + + template <class E> + Value Setter<E, float>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + float value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: double + // + template <class E> + class Setter<E, double> : public Command { + public: + /// Pointer to method that sets paramter of type double + typedef void (E::*SetterMethod) (const double&); + /// Constructor + Setter(E& entity, SetterMethod); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, double>::Setter(E& entity, SetterMethod setterMethod) : + Command(entity, boost::assign::list_of(Value::DOUBLE)), + setterMethod_(setterMethod) { - std::vector<Value::Type> result; - if (typeid(T) == typeid(int)) { - result.push_back(Value::INT); - } else if (typeid(T) == typeid(double)) { - result.push_back(Value::DOUBLE); - } else if (typeid(T) == typeid(std::string)) { - result.push_back(Value::STRING); - } else { - std::stringstream ss; - ss << "Type " << typeid(T).name() << " not supported."; - throw ExceptionAbstract(ExceptionAbstract::TOOLS, - ss.str()); - } - return result; } - template <class E, typename T> - Setter<E, T>::Setter(E& entity, SetterMethod setterMethod) : - Command(entity, typeVector()), + template <class E> + Value Setter<E, double>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + double value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: std::string + // + template <class E> + class Setter<E, std::string> : public Command { + public: + /// Pointer to method that sets paramter of type std::string + typedef void (E::*SetterMethod) (const std::string&); + /// Constructor + Setter(E& entity, SetterMethod); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, std::string>::Setter(E& entity, SetterMethod setterMethod) : + Command(entity, boost::assign::list_of(Value::STRING)), setterMethod_(setterMethod) { } - template <class E, typename T> - Value Setter<E, T>::doExecute() + template <class E> + Value Setter<E, std::string>::doExecute() { const std::vector<Value>& values = getParameterValues(); // Get parameter - T value = values[0].value(); + std::string value = values[0].value(); E& entity = static_cast<E&>(owner()); (entity.*setterMethod_)(value); return Value(); } + } // namespace command } // namespace dynamicgraph diff --git a/include/dynamic-graph/value.h b/include/dynamic-graph/value.h index d21e948..4846800 100644 --- a/include/dynamic-graph/value.h +++ b/include/dynamic-graph/value.h @@ -31,7 +31,10 @@ namespace dynamicgraph { public: EitherType(const Value& value); ~EitherType(); + operator bool () const; + operator unsigned () const; operator int () const; + operator float () const; operator double () const; operator std::string () const; private: @@ -42,13 +45,19 @@ namespace dynamicgraph { public: enum Type { NONE, + BOOL, + UNSIGNED, INT, + FLOAT, DOUBLE, STRING, NB_TYPES }; ~Value(); + Value(const bool& value); + Value(const unsigned& value); Value(const int& value); + Value(const float& value); Value(const double& value); Value(const std::string& value); /// Copy constructor @@ -77,8 +86,11 @@ namespace dynamicgraph { friend std::ostream& operator<<(std::ostream& os, const Value& value); private: friend class EitherType; - const double doubleValue() const; + const bool boolValue() const; + const unsigned unsignedValue() const; const int intValue() const; + const float floatValue() const; + const double doubleValue() const; const std::string stringValue() const; Type type_; const void* value_; diff --git a/src/command/value.cpp b/src/command/value.cpp index 7a74a27..af1bd10 100644 --- a/src/command/value.cpp +++ b/src/command/value.cpp @@ -30,10 +30,22 @@ namespace dynamicgraph { delete value_; } + EitherType::operator bool () const + { + return value_->boolValue(); + } + EitherType::operator unsigned () const + { + return value_->unsignedValue(); + } EitherType::operator int () const { return value_->intValue(); } + EitherType::operator float () const + { + return value_->floatValue(); + } EitherType::operator double () const { return value_->doubleValue(); @@ -46,9 +58,18 @@ namespace dynamicgraph { Value::~Value() { switch(type_) { + case BOOL: + delete (bool*)value_; + break; + case UNSIGNED: + delete (unsigned*)value_; + break; case INT: delete (int*)value_; break; + case FLOAT: + delete (float*)value_; + break; case DOUBLE: delete (double*)value_; break; @@ -58,21 +79,33 @@ namespace dynamicgraph { } } + Value::Value(const bool& value) + { + value_ = new bool(value); + type_ = BOOL; + } + Value::Value(const unsigned& value) + { + value_ = new unsigned(value); + type_ = UNSIGNED; + } Value::Value(const int& value) { - std::cout << "Constructor of int value" << std::endl; value_ = new int(value); type_ = INT; } + Value::Value(const float& value) + { + value_ = new float(value); + type_ = FLOAT; + } Value::Value(const double& value) { - std::cout << "Constructor of double value" << std::endl; value_ = new double(value); type_ = DOUBLE; } Value::Value(const std::string& value) { - std::cout << "Constructor of string value" << std::endl; value_ = new std::string(value); type_ = STRING; } @@ -81,16 +114,22 @@ namespace dynamicgraph { Value::Value(const Value& value) : type_(value.type_) { switch(value.type_) { + case BOOL: + value_ = new bool(value.intValue()); + break; + case UNSIGNED: + value_ = new unsigned(value.intValue()); + break; case INT: - std::cout << "Value copy constructor: int" << std::endl; value_ = new int(value.intValue()); break; + case FLOAT: + value_ = new float(value.intValue()); + break; case DOUBLE: - std::cout << "Value copy constructor: double" << std::endl; value_ = new double(value.doubleValue()); break; case STRING: - std::cout << "Value copy constructor: string" << std::endl; value_ = new std::string(value.stringValue()); break; default: @@ -101,7 +140,6 @@ namespace dynamicgraph { Value::Value() : type_(NONE), value_(NULL) { - std::cout << "Value empty constructor" << std::endl; } const EitherType Value::value() const @@ -114,14 +152,20 @@ namespace dynamicgraph { return type_; } - const double Value::doubleValue () const + const bool Value::boolValue () const { - double result; - if (type_ == DOUBLE) - result = *((double*)value_); - return result; + if (type_ == BOOL) + return *((bool*)value_); throw ExceptionAbstract(ExceptionAbstract::TOOLS, - "value is not a double"); + "value is not an bool"); + } + + const unsigned Value::unsignedValue () const + { + if (type_ == UNSIGNED) + return *((unsigned*)value_); + throw ExceptionAbstract(ExceptionAbstract::TOOLS, + "value is not an unsigned int"); } const int Value::intValue () const @@ -129,7 +173,27 @@ namespace dynamicgraph { if (type_ == INT) return *((int*)value_); throw ExceptionAbstract(ExceptionAbstract::TOOLS, - "value is not an int"); + "value is not an int int"); + } + + const float Value::floatValue () const + { + float result; + if (type_ == FLOAT) + result = *((float*)value_); + return result; + throw ExceptionAbstract(ExceptionAbstract::TOOLS, + "value is not a float"); + } + + const double Value::doubleValue () const + { + double result; + if (type_ == DOUBLE) + result = *((double*)value_); + return result; + throw ExceptionAbstract(ExceptionAbstract::TOOLS, + "value is not a double"); } const std::string Value::stringValue () const @@ -143,8 +207,14 @@ namespace dynamicgraph { std::string Value::typeName(Type type) { switch (type) { + case BOOL: + return std::string("bool"); + case UNSIGNED: + return std::string("unsigned int"); case INT: return std::string("int"); + case FLOAT: + return std::string("float"); case DOUBLE: return std::string("double"); case STRING: @@ -158,12 +228,21 @@ namespace dynamicgraph { os << "Type=" << Value::typeName(value.type_) << ", value="; switch (value.type_) { + case Value::BOOL: + os << value.boolValue(); + break; + case Value::UNSIGNED: + os << value.unsignedValue(); + break; case Value::INT: os << value.intValue(); break; case Value::DOUBLE: os << value.doubleValue(); break; + case Value::FLOAT: + os << value.floatValue(); + break; case Value::STRING: os << value.stringValue(); break; -- GitLab