From 0392614aac1077deba9d526cf7bacf5934746df5 Mon Sep 17 00:00:00 2001
From: florent <florent@laas.fr>
Date: Fri, 19 Nov 2010 17:56:19 +0100
Subject: [PATCH] Add support for vector and matrix

    * include/CMakeLists.txt,
    * include/dynamic-graph/command-setter.t.cpp,
    * include/dynamic-graph/value.h,
    * src/command/value.cpp.

    Types for vector and matrix are boost::numeric::ublas::vector<double>
    and boost::numeric::ublas::matrix<double>.
---
 include/CMakeLists.txt                     |  1 +
 include/dynamic-graph/command-setter.t.cpp | 73 ++++++++++++++++++++++
 include/dynamic-graph/linear-algebra.h     | 30 +++++++++
 include/dynamic-graph/value.h              | 23 ++++---
 src/command/value.cpp                      | 57 +++++++++++++++++
 5 files changed, 177 insertions(+), 7 deletions(-)
 create mode 100644 include/dynamic-graph/linear-algebra.h

diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 1fbec3a..b90f198 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -67,6 +67,7 @@ tracer.h
 tracer-real-time.h
 
 command.h
+linear-algebra.h
 value.h
 command-setter.h
 command-setter.t.cpp
diff --git a/include/dynamic-graph/command-setter.t.cpp b/include/dynamic-graph/command-setter.t.cpp
index 962dd8e..7d26fc4 100644
--- a/include/dynamic-graph/command-setter.t.cpp
+++ b/include/dynamic-graph/command-setter.t.cpp
@@ -20,6 +20,7 @@
 
 #include <sstream>
 #include <boost/assign/list_of.hpp>
+#include "dynamic-graph/linear-algebra.h"
 
 namespace dynamicgraph {
   class Entity;
@@ -241,6 +242,78 @@ namespace dynamicgraph {
       return Value();
     }
 
+    // 
+    // Template specialization: Vector
+    //
+    template <class E>
+    class Setter<E, Vector> : public Command {
+    public:
+      /// Pointer to method that sets paramter of type Vector
+      typedef void (E::*SetterMethod) (const Vector&);
+      /// Constructor
+      Setter(E& entity, SetterMethod);
+
+    protected:
+      virtual Value doExecute();
+
+    private:
+      SetterMethod setterMethod_;
+    }; // Class Setter
+
+    template <class E>
+    Setter<E, Vector>::Setter(E& entity, SetterMethod setterMethod) :
+      Command(entity, boost::assign::list_of(Value::VECTOR)),
+      setterMethod_(setterMethod)
+    {
+    }
+
+    template <class E>
+    Value Setter<E, Vector>::doExecute()
+    {
+      const std::vector<Value>& values = getParameterValues();
+      // Get parameter
+      Vector value = values[0].value();
+      E& entity = static_cast<E&>(owner());
+      (entity.*setterMethod_)(value);
+      return Value();
+    }
+
+    // 
+    // Template specialization: Matrix
+    //
+    template <class E>
+    class Setter<E, Matrix> : public Command {
+    public:
+      /// Pointer to method that sets paramter of type Matrix
+      typedef void (E::*SetterMethod) (const Matrix&);
+      /// Constructor
+      Setter(E& entity, SetterMethod);
+
+    protected:
+      virtual Value doExecute();
+
+    private:
+      SetterMethod setterMethod_;
+    }; // Class Setter
+
+    template <class E>
+    Setter<E, Matrix>::Setter(E& entity, SetterMethod setterMethod) :
+      Command(entity, boost::assign::list_of(Value::MATRIX)),
+      setterMethod_(setterMethod)
+    {
+    }
+
+    template <class E>
+    Value Setter<E, Matrix>::doExecute()
+    {
+      const std::vector<Value>& values = getParameterValues();
+      // Get parameter
+      Matrix 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/linear-algebra.h b/include/dynamic-graph/linear-algebra.h
new file mode 100644
index 0000000..0ec3dd1
--- /dev/null
+++ b/include/dynamic-graph/linear-algebra.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2010 CNRS
+//
+// Author: Florent Lamiraux
+//
+// 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_LINEAR_ALGEBRA_H
+#define DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+namespace dynamicgraph {
+  typedef ::boost::numeric::ublas::vector<double> Vector;
+  typedef ::boost::numeric::ublas::matrix<double> Matrix;
+}
+
+#endif //DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
+
+
diff --git a/include/dynamic-graph/value.h b/include/dynamic-graph/value.h
index 5346afb..f7d6deb 100644
--- a/include/dynamic-graph/value.h
+++ b/include/dynamic-graph/value.h
@@ -23,6 +23,7 @@
 #include <cassert>
 #include <typeinfo>
 #include "dynamic-graph/dynamic-graph-api.h"
+#include "dynamic-graph/linear-algebra.h"
 
 namespace dynamicgraph {
   namespace command {
@@ -37,6 +38,8 @@ namespace dynamicgraph {
       operator float () const;
       operator double () const;
       operator std::string () const;
+      operator Vector () const;
+      operator Matrix () const;
     private:
       const Value* value_;
     };
@@ -51,19 +54,23 @@ namespace dynamicgraph {
 	FLOAT,
 	DOUBLE,
 	STRING,
+	VECTOR,
+	MATRIX,
 	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);
+      explicit Value(const bool& value);
+      explicit Value(const unsigned& value);
+      explicit Value(const int& value);
+      explicit Value(const float& value);
+      explicit Value(const double& value);
+      explicit Value(const std::string& value);
+      explicit Value(const Vector& value);
+      explicit Value(const Matrix& value);
       /// Copy constructor
       Value(const Value& value);
       // Construct an empty value (None)
-      Value();
+      explicit Value();
       /// Return the type of the value
       Type type() const;
 
@@ -92,6 +99,8 @@ namespace dynamicgraph {
       float floatValue() const;
       double doubleValue() const;
       std::string stringValue() const;
+      Vector vectorValue() const;
+      Matrix matrixValue() const;
       Type type_;
       const void* value_;
     };
diff --git a/src/command/value.cpp b/src/command/value.cpp
index b965bf3..4e699bd 100644
--- a/src/command/value.cpp
+++ b/src/command/value.cpp
@@ -15,6 +15,7 @@
 // have received a copy of the GNU Lesser General Public License along
 // with dynamic-graph.  If not, see <http://www.gnu.org/licenses/>.
 
+#include <boost/numeric/ublas/io.hpp>
 #include "dynamic-graph/value.h"
 #include "dynamic-graph/exception-abstract.h"
 
@@ -54,6 +55,14 @@ namespace dynamicgraph {
     {
       return value_->stringValue();
     }
+    EitherType::operator Vector () const
+    {
+      return value_->vectorValue();
+    }
+    EitherType::operator Matrix () const
+    {
+      return value_->matrixValue();
+    }
 
     Value::~Value()
     {
@@ -76,6 +85,12 @@ namespace dynamicgraph {
       case STRING:
 	delete (std::string*)value_;
 	break;
+      case VECTOR:
+	delete (Vector*)value_;
+	break;
+      case MATRIX:
+	delete (Matrix*)value_;
+	break;
       default:;
       }
     }
@@ -110,6 +125,16 @@ namespace dynamicgraph {
       value_ = new std::string(value);
       type_ = STRING;
     }
+    Value::Value(const Vector& value)
+    {
+      value_ = new Vector(value);
+      type_ = VECTOR;
+    }
+    Value::Value(const Matrix& value)
+    {
+      value_ = new Matrix(value);
+      type_ = MATRIX;
+    }
 
 
     Value::Value(const Value& value) : type_(value.type_)
@@ -133,6 +158,12 @@ namespace dynamicgraph {
       case STRING:
 	value_ = new std::string(value.stringValue());
 	break;
+      case VECTOR:
+	value_ = new Vector(value.vectorValue());
+	break;
+      case MATRIX:
+	value_ = new Matrix(value.matrixValue());
+	break;
       default:
 	type_ = NONE;
 	value_ = NULL;
@@ -205,6 +236,22 @@ namespace dynamicgraph {
 			      "value is not an string");
     }
 
+    Vector Value::vectorValue () const
+    {
+      if (type_ == VECTOR)
+	return *((Vector*)value_);
+      throw ExceptionAbstract(ExceptionAbstract::TOOLS,
+			      "value is not an vector");
+    }
+
+    Matrix Value::matrixValue () const
+    {
+      if (type_ == MATRIX)
+	return *((Matrix*)value_);
+      throw ExceptionAbstract(ExceptionAbstract::TOOLS,
+			      "value is not a matrix");
+    }
+
     std::string Value::typeName(Type type)
     {
       switch (type) {
@@ -220,6 +267,10 @@ namespace dynamicgraph {
 	return std::string("double");
       case STRING:
 	return std::string("string");
+      case VECTOR:
+	return std::string("vector");
+      case MATRIX:
+	return std::string("matrix");
       default:
 	return std::string("unknown");
       }
@@ -248,6 +299,12 @@ namespace dynamicgraph {
       case Value::STRING:
 	os << value.stringValue();
 	break;
+      case Value::VECTOR:
+	os << value.vectorValue();
+	break;
+      case Value::MATRIX:
+	os << value.matrixValue();
+	break;
       default:
 	return os;
       }
-- 
GitLab