diff --git a/Eigen/src/Core/Map.h b/Eigen/src/Core/Map.h index 7dfaac273..99061f77f 100644 --- a/Eigen/src/Core/Map.h +++ b/Eigen/src/Core/Map.h @@ -40,9 +40,9 @@ * It can be used to let Eigen interface without any overhead with non-Eigen data structures, * such as plain C arrays or structures from other libraries. * - * This class is the return type of Matrix::map() but can also be used directly. + * This class is the return type of Matrix::Map() but can also be used directly. * - * \sa Matrix::map() + * \sa Matrix::Map() */ template struct ei_traits > : public ei_traits @@ -106,13 +106,13 @@ template class Map * for the dimensions. * * \sa Matrix(const Scalar *, int), Matrix(const Scalar *, int, int), - * Matrix::map(const Scalar *) + * Matrix::Map(const Scalar *) */ template inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> ::Matrix(const Scalar *data) { - *this = Map(data); + *this = Eigen::Map(data); } #endif // EIGEN_MAP_H diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 5b95a0a5e..bf579dc9e 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -108,7 +108,9 @@ class Matrix public: EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) friend class Eigen::Map; + typedef class Eigen::Map UnalignedMapType; friend class Eigen::Map; + typedef class Eigen::Map AlignedMapType; protected: ei_matrix_storage m_storage; @@ -406,7 +408,7 @@ class Matrix /** Override MatrixBase::eval() since matrices don't need to be evaluated, it is enough to just read them. * This prevents a useless copy when doing e.g. "m1 = m2.eval()" */ - const Matrix& eval() const + inline const Matrix& eval() const { return *this; } @@ -414,7 +416,7 @@ class Matrix /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the * data pointers. */ - void swap(Matrix& other) + inline void swap(Matrix& other) { if (Base::SizeAtCompileTime==Dynamic) m_storage.swap(other.m_storage); @@ -422,6 +424,41 @@ class Matrix this->Base::swap(other); } + /** + * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, + * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned + * \a data pointers. + * + * \see class Map + */ + //@} + inline static const UnalignedMapType Map(const Scalar* data) + { return UnalignedMapType(data); } + inline static UnalignedMapType Map(Scalar* data) + { return UnalignedMapType(data); } + inline static const UnalignedMapType Map(const Scalar* data, int size) + { return UnalignedMapType(data, size); } + inline static UnalignedMapType Map(Scalar* data, int size) + { return UnalignedMapType(data, size); } + inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols) + { return UnalignedMapType(data, rows, cols); } + inline static UnalignedMapType Map(Scalar* data, int rows, int cols) + { return UnalignedMapType(data, rows, cols); } + + inline static const AlignedMapType MapAligned(const Scalar* data) + { return AlignedMapType(data); } + inline static AlignedMapType MapAligned(Scalar* data) + { return AlignedMapType(data); } + inline static const AlignedMapType MapAligned(const Scalar* data, int size) + { return AlignedMapType(data, size); } + inline static AlignedMapType MapAligned(Scalar* data, int size) + { return AlignedMapType(data, size); } + inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols) + { return AlignedMapType(data, rows, cols); } + inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols) + { return AlignedMapType(data, rows, cols); } + //@} + /////////// Geometry module /////////// template diff --git a/test/map.cpp b/test/map.cpp index 705a74c3a..c416e164c 100644 --- a/test/map.cpp +++ b/test/map.cpp @@ -24,7 +24,7 @@ #include "main.h" -template void tmap(const VectorType& m) +template void map_class(const VectorType& m) { typedef typename VectorType::Scalar Scalar; @@ -50,13 +50,46 @@ template void tmap(const VectorType& m) delete[] array3; } +template void map_static_methods(const VectorType& m) +{ + typedef typename VectorType::Scalar Scalar; + + int size = m.size(); + + // test Map.h + Scalar* array1 = ei_aligned_malloc(size); + Scalar* array2 = ei_aligned_malloc(size); + Scalar* array3 = new Scalar[size+1]; + Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3; + + VectorType::MapAligned(array1, size) = VectorType::Random(size); + VectorType::Map(array2, size) = VectorType::Map(array1, size); + VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size); + VectorType ma1 = VectorType::Map(array1, size); + VectorType ma2 = VectorType::MapAligned(array2, size); + VectorType ma3 = VectorType::Map(array3unaligned, size); + VERIFY_IS_APPROX(ma1, ma2); + VERIFY_IS_APPROX(ma1, ma3); + + ei_aligned_free(array1); + ei_aligned_free(array2); + delete[] array3; +} + + void test_map() { for(int i = 0; i < g_repeat; i++) { - CALL_SUBTEST( tmap(Matrix()) ); - CALL_SUBTEST( tmap(Vector4d()) ); - CALL_SUBTEST( tmap(RowVector4f()) ); - CALL_SUBTEST( tmap(VectorXcf(8)) ); - CALL_SUBTEST( tmap(VectorXi(12)) ); + CALL_SUBTEST( map_class(Matrix()) ); + CALL_SUBTEST( map_class(Vector4d()) ); + CALL_SUBTEST( map_class(RowVector4f()) ); + CALL_SUBTEST( map_class(VectorXcf(8)) ); + CALL_SUBTEST( map_class(VectorXi(12)) ); + + CALL_SUBTEST( map_static_methods(Matrix()) ); + CALL_SUBTEST( map_static_methods(Vector3f()) ); + CALL_SUBTEST( map_static_methods(RowVector3d()) ); + CALL_SUBTEST( map_static_methods(VectorXcd(8)) ); + CALL_SUBTEST( map_static_methods(VectorXf(12)) ); } }