aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Hauke Heibel <hauke.heibel@gmail.com>2010-01-27 20:34:05 +0100
committerGravatar Hauke Heibel <hauke.heibel@gmail.com>2010-01-27 20:34:05 +0100
commit5b9cc65418be7539db01f87712ed32d3f22517a5 (patch)
treeccc72d0b9e0b85bb70ea744811c9952222127bc7
parent828d058b4b340a467da7f7bea6bb29522a6565f9 (diff)
Added EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION macro including unit tests and documentation.
-rw-r--r--Eigen/StdVector39
-rw-r--r--doc/D01_StlContainers.dox15
-rw-r--r--doc/snippets/DenseBase_LinSpaced.cpp4
-rw-r--r--test/CMakeLists.txt1
4 files changed, 57 insertions, 2 deletions
diff --git a/Eigen/StdVector b/Eigen/StdVector
index b6dbde8a2..04e356785 100644
--- a/Eigen/StdVector
+++ b/Eigen/StdVector
@@ -29,6 +29,45 @@
#include "Core"
#include <vector>
+// Define the explicit instantiation (e.g. necessary for the Intel compiler)
+#if defined(__INTEL_COMPILER) || defined(__GNUC__)
+ #define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...) template class std::vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >;
+#else
+ #define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...)
+#endif
+
+/**
+ * This section contains a convenience MACRO which allows an easy specialization of
+ * std::vector such that for data types with alignment issues the correct allocator
+ * is used automatically.
+ */
+#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \
+EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(__VA_ARGS__) \
+namespace std \
+{ \
+ template<typename _Ay> \
+ class vector<__VA_ARGS__, _Ay> \
+ : public vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \
+ { \
+ typedef vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > vector_base; \
+ public: \
+ typedef __VA_ARGS__ value_type; \
+ typedef typename vector_base::allocator_type allocator_type; \
+ typedef typename vector_base::size_type size_type; \
+ typedef typename vector_base::iterator iterator; \
+ explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
+ template<typename InputIterator> \
+ vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \
+ vector(const vector& c) : vector_base(c) {} \
+ explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
+ vector(iterator start, iterator end) : vector_base(start, end) {} \
+ vector& operator=(const vector& x) { \
+ vector_base::operator=(x); \
+ return *this; \
+ } \
+ }; \
+}
+
namespace Eigen {
// This one is needed to prevent reimplementing the whole std::vector.
diff --git a/doc/D01_StlContainers.dox b/doc/D01_StlContainers.dox
index db682c996..83e930e50 100644
--- a/doc/D01_StlContainers.dox
+++ b/doc/D01_StlContainers.dox
@@ -41,6 +41,21 @@ Here is an example:
std::vector<Eigen::Vector4f,Eigen::aligned_allocator<Eigen::Vector4f> >
\endcode
+\subsection vector_spec An alternative - specializing std::vector for Eigen types
+
+As an alternative to the recommended approach described above, you have the option to specialize std::vector for Eigen types requiring alignment.
+The advantage is that you won't need to declare std::vector all over with Eigen::allocator. One drawback on the other hand side is that
+the specialization needs to be defined before all code pieces in which e.g. std::vector<Vector2d> is used. Otherwise, without knowing the specialization
+the compiler will compile that particular instance with the default std::allocator and you program is most likely to crash.
+
+Here is an example:
+\code
+#include<Eigen/StdVector>
+\/* ... *\/
+EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d)
+std::vector<Eigen::Vector2d>
+\endcode
+
<span class="note">\b Explanation: The resize() method of std::vector takes a value_type argument (defaulting to value_type()). So with std::vector<Eigen::Vector4f>, some Eigen::Vector4f objects will be passed by value, which discards any alignment modifiers, so a Eigen::Vector4f can be created at an unaligned location. In order to avoid that, the only solution we saw was to specialize std::vector to make it work on a slight modification of, here, Eigen::Vector4f, that is able to deal properly with this situation.
</span>
diff --git a/doc/snippets/DenseBase_LinSpaced.cpp b/doc/snippets/DenseBase_LinSpaced.cpp
index 540709adc..c8c3e972c 100644
--- a/doc/snippets/DenseBase_LinSpaced.cpp
+++ b/doc/snippets/DenseBase_LinSpaced.cpp
@@ -1,2 +1,2 @@
-cout << VectorXi::LinSpaced(7,10,4) << endl;
-cout << VectorXd::LinSpaced(0.0,1.0,5) << endl;
+cout << VectorXi::LinSpaced(7,10,4).transpose() << endl;
+cout << VectorXd::LinSpaced(0.0,1.0,5).transpose() << endl;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1177db797..77e7a5fd2 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -152,6 +152,7 @@ ei_add_test(geo_parametrizedline)
ei_add_test(geo_alignedbox)
ei_add_test(regression)
ei_add_test(stdvector)
+ei_add_test(stdvector_overload)
ei_add_test(resize)
if(QT4_FOUND)
ei_add_test(qtvector " " "${QT_QTCORE_LIBRARY}")