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 +// 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 \ + 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 \ + 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 > \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 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_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d) +std::vector +\endcode + \b Explanation: The resize() method of std::vector takes a value_type argument (defaulting to value_type()). So with std::vector, 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. 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}")