From 242f086a0f4ffd4ba59b7b006519d7f71b0f0cfc Mon Sep 17 00:00:00 2001
From: Thomas Moulard <thomas.moulard@gmail.com>
Date: Tue, 28 Dec 2010 00:18:28 +0100
Subject: [PATCH] Convert test_signalcast into unit test.

---
 tests/CMakeLists.txt                  |   4 +-
 tests/signal-cast-registerer-libA.cpp |  18 +++
 tests/signal-cast-registerer-libA.hh  |  20 +++
 tests/signal-cast-registerer-libB.cpp |  18 +++
 tests/signal-cast-registerer-libB.hh  |  20 +++
 tests/signal-cast-registerer.cpp      | 189 ++++++++++++++++++++++++++
 tests/test_signalcast.cpp             | 135 ------------------
 tests/test_signalcast_libA.cpp        |  37 -----
 tests/test_signalcast_libA.h          |  25 ----
 tests/test_signalcast_libB.cpp        |  35 -----
 tests/test_signalcast_libB.h          |  25 ----
 11 files changed, 267 insertions(+), 259 deletions(-)
 create mode 100644 tests/signal-cast-registerer-libA.cpp
 create mode 100644 tests/signal-cast-registerer-libA.hh
 create mode 100644 tests/signal-cast-registerer-libB.cpp
 create mode 100644 tests/signal-cast-registerer-libB.hh
 create mode 100644 tests/signal-cast-registerer.cpp
 delete mode 100644 tests/test_signalcast.cpp
 delete mode 100644 tests/test_signalcast_libA.cpp
 delete mode 100644 tests/test_signalcast_libA.h
 delete mode 100644 tests/test_signalcast_libB.cpp
 delete mode 100644 tests/test_signalcast_libB.h

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7a067560..c2c36ad9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -42,7 +42,7 @@ ENDMACRO(DYNAMIC_GRAPH_TEST)
 
 
 # Signal cast test.
-SET(signalcast_libs test_signalcast_libA test_signalcast_libB)
+SET(signalcast_libs signal-cast-registerer-libA signal-cast-registerer-libB)
 
 FOREACH(lib ${signalcast_libs})
   ADD_LIBRARY(${lib} SHARED ${lib}.cpp)
@@ -50,7 +50,7 @@ FOREACH(lib ${signalcast_libs})
   TARGET_LINK_LIBRARIES(${lib} ${PROJECT_NAME})
   ADD_DEPENDENCIES(${lib} ${PROJECT_NAME})
 ENDFOREACH()
-DYNAMIC_GRAPH_TEST(test_signalcast)
+DYNAMIC_GRAPH_TEST(signal-cast-registerer)
 TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} ${signalcast_libs})
 
 # Unit testing.
diff --git a/tests/signal-cast-registerer-libA.cpp b/tests/signal-cast-registerer-libA.cpp
new file mode 100644
index 00000000..b403e894
--- /dev/null
+++ b/tests/signal-cast-registerer-libA.cpp
@@ -0,0 +1,18 @@
+// Copyright 2010 Thomas Moulard.
+//
+// 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 "signal-cast-registerer-libA.hh"
+
+vec_type vA;
diff --git a/tests/signal-cast-registerer-libA.hh b/tests/signal-cast-registerer-libA.hh
new file mode 100644
index 00000000..7dcdd3bc
--- /dev/null
+++ b/tests/signal-cast-registerer-libA.hh
@@ -0,0 +1,20 @@
+// Copyright 2010 Thomas Moulard.
+//
+// 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 <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+typedef boost::numeric::ublas::vector<double> vec_type;
+extern vec_type vA;
diff --git a/tests/signal-cast-registerer-libB.cpp b/tests/signal-cast-registerer-libB.cpp
new file mode 100644
index 00000000..a8ce1b1a
--- /dev/null
+++ b/tests/signal-cast-registerer-libB.cpp
@@ -0,0 +1,18 @@
+// Copyright 2010 Thomas Moulard.
+//
+// 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 "signal-cast-registerer-libB.hh"
+
+vec_type vB;
diff --git a/tests/signal-cast-registerer-libB.hh b/tests/signal-cast-registerer-libB.hh
new file mode 100644
index 00000000..ea04629e
--- /dev/null
+++ b/tests/signal-cast-registerer-libB.hh
@@ -0,0 +1,20 @@
+// Copyright 2010 Thomas Moulard.
+//
+// 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 <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+typedef boost::numeric::ublas::vector<double> vec_type;
+extern vec_type vB;
diff --git a/tests/signal-cast-registerer.cpp b/tests/signal-cast-registerer.cpp
new file mode 100644
index 00000000..eda97b1e
--- /dev/null
+++ b/tests/signal-cast-registerer.cpp
@@ -0,0 +1,189 @@
+// Copyright 2010 Thomas Moulard.
+//
+// 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 <string>
+
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include <dynamic-graph/debug.h>
+#include <dynamic-graph/entity.h>
+#include <dynamic-graph/factory.h>
+#include <dynamic-graph/pool.h>
+#include <dynamic-graph/signal-caster.h>
+#include <dynamic-graph/signal.h>
+
+#include "signal-cast-registerer-libA.hh"
+#include "signal-cast-registerer-libB.hh"
+
+#define BOOST_TEST_MODULE signal_cast_registerer
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/output_test_stream.hpp>
+
+using boost::test_tools::output_test_stream;
+
+
+typedef boost::numeric::ublas::vector<double> Vector;
+
+
+struct BoostNumericsCastRegisterer : public dynamicgraph::SignalCastRegisterer
+{
+  typedef boost::numeric::ublas::vector<double> bnuVector;
+
+  BoostNumericsCastRegisterer () :
+    SignalCastRegisterer
+    (typeid(bnuVector), dispVector, castVector, traceVector)
+  {}
+
+  static boost::any castVector (std::istringstream& iss)
+  {
+    bnuVector res;
+    iss >> res;
+    return res;
+  }
+
+  static void dispVector (const boost::any& object, std::ostream& os)
+  {
+    const bnuVector& v = boost::any_cast<bnuVector> (object);
+    os << "[ ";
+    for (unsigned int i = 0; i < v.size (); ++i)
+      os << v(i) << " ";
+    os << " ];" << std::endl;
+  }
+
+  static void traceVector (const boost::any& object, std::ostream& os)
+  {
+    const bnuVector& v = boost::any_cast<bnuVector> (object);
+    for (unsigned int i = 0; i < v.size (); ++i)
+      os << v(i) << " ";
+    os << std::endl;
+  }
+};
+
+BoostNumericsCastRegisterer myVectorCast;
+
+// Define a new cast with a type that supports streaming operators to
+// and from it (this could be automated with macros).
+dynamicgraph::DefaultCastRegisterer<bool> myBooleanCast;
+
+
+// Check standard double cast registerer.
+BOOST_AUTO_TEST_CASE (standard_double_registerer)
+{
+  dynamicgraph::Signal<double, int> mySignal("out");
+
+  typedef std::pair<std::string, std::string> test_t;
+  std::vector<test_t> values;
+
+  values.push_back (std::make_pair ("42.0", "42\n"));
+  values.push_back (std::make_pair ("42.5", "42.5\n"));
+  values.push_back (std::make_pair ("-12.", "-12\n"));
+
+  // Double special values.
+  // FIXME: these tests are failing :(
+  values.push_back (std::make_pair ("inf", "inf\n"));
+  values.push_back (std::make_pair ("-inf", "-inf\n"));
+  values.push_back (std::make_pair ("nan", "nan\n"));
+
+  BOOST_FOREACH(const test_t& test, values)
+    {
+      // Set
+      std::istringstream value (test.first);
+      mySignal.set (value);
+
+      // Get
+      {
+	output_test_stream output;
+	mySignal.get (output);
+	BOOST_CHECK (output.is_equal (test.second));
+      }
+
+      // Trace
+      {
+	output_test_stream output;
+	mySignal.trace (output);
+	BOOST_CHECK (output.is_equal (test.second));
+      }
+    }
+
+  // Check invalid values.
+  // FIXME: this test is failing for now.
+  std::istringstream value ("This is not a valid double.");
+  BOOST_CHECK_THROW (mySignal.set (value), std::exception);
+}
+
+
+// Check a custom cast registerer for Boost uBLAS vectors.
+BOOST_AUTO_TEST_CASE (custom_vector_registerer)
+{
+  namespace ublas = boost::numeric::ublas;
+
+  dynamicgraph::Signal<Vector, int> myVectorSignal("vector");
+
+  // Print the signal name.
+  {
+    output_test_stream output;
+    output << myVectorSignal;
+    BOOST_CHECK (output.is_equal ("Sig:vector (Type Cst)"));
+  }
+
+  for (int i = 0; i < 5; ++i)
+    {
+      ublas::unit_vector<double> v (5, i);
+      std::ostringstream os;
+      os << v;
+      std::istringstream ss (os.str ());
+
+      // Set signal value.
+      myVectorSignal.set (ss);
+
+      // Print out signal value.
+      output_test_stream output;
+      myVectorSignal.get (output);
+
+      boost::format fmt ("[ %d %d %d %d %d  ];\n");
+      fmt
+	% (i == 0)
+	% (i == 1)
+	% (i == 2)
+	% (i == 3)
+	% (i == 4);
+
+      BOOST_CHECK (output.is_equal (fmt.str ()));
+    }
+}
+
+
+// One issue with the strategy used by the
+// dynamicgraph::SignalCastRegisterer is that it relies on the
+// typeid. In practice, it means that two signals defined in two
+// different libraries will have different typeid and one will not be
+// able to plug one into the other unless the symbol have merged when
+// the plug-in is loaded. See man(3) dlopen in Linux for more
+// information about plug-in loading and the RTLD_GLOBAL flag
+// necessary to make cast registerer work as expected.
+//
+// Here we make sure that two instances of the same type
+// declared in two separate libraries are resolved into the
+// same typeid.
+BOOST_AUTO_TEST_CASE (typeid_issue)
+{
+  BOOST_CHECK (typeid(vA) == typeid(vB));
+  BOOST_CHECK_EQUAL (std::string (typeid(vA).name ()),
+		     std::string (typeid(vB).name ()));
+}
diff --git a/tests/test_signalcast.cpp b/tests/test_signalcast.cpp
deleted file mode 100644
index 682d2d4d..00000000
--- a/tests/test_signalcast.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2010,
- * François Bleibel,
- * Olivier Stasse,
- *
- * CNRS/AIST
- *
- * 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/>.
- */
-
-/* -------------------------------------------------------------------------- */
-/* --- INCLUDES ------------------------------------------------------------- */
-/* -------------------------------------------------------------------------- */
-
-
-#include <string>
-#include <iostream>
-#include <cstdlib>
-#include <memory>
-
-#include <dynamic-graph/factory.h>
-#include <dynamic-graph/entity.h>
-#include <dynamic-graph/debug.h>
-#include <dynamic-graph/pool.h>
-#include <dynamic-graph/signal.h>
-// only included because we will define new casts here. Not needed in general.
-#include <dynamic-graph/signal-caster.h>
-
-#include "test_signalcast_libA.h"
-#include "test_signalcast_libB.h"
-
-
-using namespace std;
-using namespace dynamicgraph;
-
-// define a new cast with a ublas vector
-#include <boost/numeric/ublas/vector.hpp>
-// this header is *needed* to define iostream& operators << and >> for a ublas vector
-#include <boost/numeric/ublas/io.hpp>
-typedef boost::numeric::ublas::vector<double> Vector;
-// define a new cast with a type that supports streaming operators to and from it
-// (this could be automated with macros)
-namespace {
-	DefaultCastRegisterer<bool> myBooleanCast;
-}
-
-#include <boost/numeric/ublas/vector.hpp>
-#include <boost/numeric/ublas/io.hpp>
-class BoostNumericsCastRegisterer
-  : public SignalCastRegisterer
-{
-  typedef boost::numeric::ublas::vector<double> bnuVector;
-
-  static boost::any castVector(std::istringstream& iss)
-  {  bnuVector res; iss >> res; return res; }
-  static void dispVector(const boost::any& object, std::ostream& os)
-  {
-    const bnuVector & v = boost::any_cast<bnuVector>(object);
-    os << "[ ";
-    for( unsigned int i=0;i<v.size();++i ) os << v(i) << " ";
-    os << " ];" << std::endl;
-  }
-  static void traceVector(const boost::any& object, std::ostream& os)
-  {
-    const bnuVector & v = boost::any_cast<bnuVector>(object);
-    for( unsigned int i=0;i<v.size();++i ) os << v(i) << " ";
-    os << std::endl;
-  }
-public:
-  BoostNumericsCastRegisterer(void)
-    : SignalCastRegisterer(typeid(bnuVector),dispVector,castVector,traceVector) {}
-};
-
-BoostNumericsCastRegisterer myVectorCast;
-
-int main() {
-	using namespace boost::numeric::ublas;
-
-	Signal<double, int> mySignal("out");
-	istringstream value("42.0");
-	cout << "[cast] Setting signal value to " << value.str() << endl;
-	mySignal.set(value); // use "set" operation
-	cout << "[disp] The value read is ";
-	mySignal.get(cout);
-	cout << "[trace] Printing out trace: ";
-	mySignal.trace(cout);
-
-
-	Signal<Vector, int> myVectorSignal("vector");
-	// print out signal name
-	cout << "  " << myVectorSignal << endl;
-
-	cout << "[disp] Enumerating boost unit vectors" << endl;
-	for (int i = 0; i < 5; ++ i) {
-		unit_vector<double> v (5, i);
-		std::ostringstream os;
-		os << v;
-		std::istringstream ss(os.str());
-		myVectorSignal.set(ss);
-		// print out signal value
-		try{myVectorSignal.get(cout);}
-		catch( const ExceptionAbstract & exp ) { cout << exp << std::endl; }
-		cout << endl;
-	}
-
-	// check the following: "typeid of vA is different from typeid of vB
-	// in different shared libraries""
-	cout << "-- check typeid equality in shared libs" << endl;
-	if(typeid(vA) == typeid(vB)) {
-		cout << "The types of vA (libA.so) and vB (libB.so) are equal" << endl;
-	} else {
-		cout << "The types of vA (libA.so) and vB (libB.so) are different" << endl;
-	}
-
-	cout << "-- check type *name* equality in shared libs with type:" << endl
-			<< "  " << typeid(vA).name() << endl;
-	if( !strcmp(typeid(vA).name(), typeid(vB).name()) ) {
-		cout << "The type names of vA (libA.so) and vB (libB.so) are equal" << endl;
-	} else {
-		cout << "The type names of vA (libA.so) and vB (libB.so) are different" << endl;
-	}
-
-
-	return 0;
-}
diff --git a/tests/test_signalcast_libA.cpp b/tests/test_signalcast_libA.cpp
deleted file mode 100644
index 12853f7a..00000000
--- a/tests/test_signalcast_libA.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2010,
- * François Bleibel,
- * Olivier Stasse,
- *
- * CNRS/AIST
- *
- * 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 <string>
-#include <iostream>
-#include <cstdlib>
-#include <memory>
-
-#include <dynamic-graph/factory.h>
-#include <dynamic-graph/entity.h>
-#include <dynamic-graph/debug.h>
-#include <dynamic-graph/pool.h>
-#include <dynamic-graph/signal.h>
-#include <dynamic-graph/signal-caster.h>
-#include "test_signalcast_libA.h"
-
-using namespace dynamicgraph;
-using namespace std;
-
-vec_type vA;
diff --git a/tests/test_signalcast_libA.h b/tests/test_signalcast_libA.h
deleted file mode 100644
index 7569d373..00000000
--- a/tests/test_signalcast_libA.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2010,
- * François Bleibel,
- * Olivier Stasse,
- *
- * CNRS/AIST
- *
- * 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 <boost/numeric/ublas/vector.hpp>
-#include <boost/numeric/ublas/io.hpp>
-
-typedef boost::numeric::ublas::vector<double> vec_type;
-extern vec_type vA;
diff --git a/tests/test_signalcast_libB.cpp b/tests/test_signalcast_libB.cpp
deleted file mode 100644
index ecd362ae..00000000
--- a/tests/test_signalcast_libB.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2010,
- * François Bleibel,
- * Olivier Stasse,
- *
- * CNRS/AIST
- *
- * 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 <string>
-#include <iostream>
-
-#include <dynamic-graph/factory.h>
-#include <dynamic-graph/entity.h>
-#include <dynamic-graph/debug.h>
-#include <dynamic-graph/pool.h>
-#include <dynamic-graph/signal.h>
-#include <dynamic-graph/signal-caster.h>
-
-#include "test_signalcast_libB.h"
-using namespace dynamicgraph;
-using namespace std;
-
-vec_type vB;
diff --git a/tests/test_signalcast_libB.h b/tests/test_signalcast_libB.h
deleted file mode 100644
index 4359300b..00000000
--- a/tests/test_signalcast_libB.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2010,
- * François Bleibel,
- * Olivier Stasse,
- *
- * CNRS/AIST
- *
- * 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 <boost/numeric/ublas/vector.hpp>
-#include <boost/numeric/ublas/io.hpp>
-
-typedef boost::numeric::ublas::vector<double> vec_type;
-extern vec_type vB;
-- 
GitLab