Squashed 'third_party/eigen/' changes from 61d72f6..cf794d3


Change-Id: I9b814151b01f49af6337a8605d0c42a3a1ed4c72
git-subtree-dir: third_party/eigen
git-subtree-split: cf794d3b741a6278df169e58461f8529f43bce5d
diff --git a/test/mapped_matrix.cpp b/test/mapped_matrix.cpp
index 58904fa..bc8a694 100644
--- a/test/mapped_matrix.cpp
+++ b/test/mapped_matrix.cpp
@@ -13,30 +13,34 @@
 
 #include "main.h"
 
+#define EIGEN_TESTMAP_MAX_SIZE 256
+
 template<typename VectorType> void map_class_vector(const VectorType& m)
 {
-  typedef typename VectorType::Index Index;
   typedef typename VectorType::Scalar Scalar;
 
   Index size = m.size();
 
-  // test Map.h
   Scalar* array1 = internal::aligned_new<Scalar>(size);
   Scalar* array2 = internal::aligned_new<Scalar>(size);
   Scalar* array3 = new Scalar[size+1];
-  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
+  Scalar* array3unaligned = (internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES) == 0 ? array3+1 : array3;
+  Scalar  array4[EIGEN_TESTMAP_MAX_SIZE];
 
-  Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);
-  Map<VectorType, Aligned>(array2, size) = Map<VectorType,Aligned>(array1, size);
+  Map<VectorType, AlignedMax>(array1, size) = VectorType::Random(size);
+  Map<VectorType, AlignedMax>(array2, size) = Map<VectorType,AlignedMax>(array1, size);
   Map<VectorType>(array3unaligned, size) = Map<VectorType>(array1, size);
-  VectorType ma1 = Map<VectorType, Aligned>(array1, size);
-  VectorType ma2 = Map<VectorType, Aligned>(array2, size);
+  Map<VectorType>(array4, size)          = Map<VectorType,AlignedMax>(array1, size);
+  VectorType ma1 = Map<VectorType, AlignedMax>(array1, size);
+  VectorType ma2 = Map<VectorType, AlignedMax>(array2, size);
   VectorType ma3 = Map<VectorType>(array3unaligned, size);
+  VectorType ma4 = Map<VectorType>(array4, size);
   VERIFY_IS_EQUAL(ma1, ma2);
   VERIFY_IS_EQUAL(ma1, ma3);
+  VERIFY_IS_EQUAL(ma1, ma4);
   #ifdef EIGEN_VECTORIZE
-  if(internal::packet_traits<Scalar>::Vectorizable)
-    VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size)))
+  if(internal::packet_traits<Scalar>::Vectorizable && size>=AlignedMax)
+    VERIFY_RAISES_ASSERT((Map<VectorType,AlignedMax>(array3unaligned, size)))
   #endif
 
   internal::aligned_delete(array1, size);
@@ -46,27 +50,68 @@
 
 template<typename MatrixType> void map_class_matrix(const MatrixType& m)
 {
-  typedef typename MatrixType::Index Index;
   typedef typename MatrixType::Scalar Scalar;
 
   Index rows = m.rows(), cols = m.cols(), size = rows*cols;
+  Scalar s1 = internal::random<Scalar>();
 
-  // test Map.h
+  // array1 and array2 -> aligned heap allocation
   Scalar* array1 = internal::aligned_new<Scalar>(size);
   for(int i = 0; i < size; i++) array1[i] = Scalar(1);
   Scalar* array2 = internal::aligned_new<Scalar>(size);
   for(int i = 0; i < size; i++) array2[i] = Scalar(1);
+  // array3unaligned -> unaligned pointer to heap
   Scalar* array3 = new Scalar[size+1];
-  for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
-  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
-  Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
-  Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
-  Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
-  MatrixType ma1 = Map<MatrixType>(array1, rows, cols);
-  MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);
+  Index sizep1 = size + 1; // <- without this temporary MSVC 2103 generates bad code
+  for(Index i = 0; i < sizep1; i++) array3[i] = Scalar(1);
+  Scalar* array3unaligned = (internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES) == 0 ? array3+1 : array3;
+  Scalar array4[256];
+  if(size<=256)
+    for(int i = 0; i < size; i++) array4[i] = Scalar(1);
+  
+  Map<MatrixType> map1(array1, rows, cols);
+  Map<MatrixType, AlignedMax> map2(array2, rows, cols);
+  Map<MatrixType> map3(array3unaligned, rows, cols);
+  Map<MatrixType> map4(array4, rows, cols);
+  
+  VERIFY_IS_EQUAL(map1, MatrixType::Ones(rows,cols));
+  VERIFY_IS_EQUAL(map2, MatrixType::Ones(rows,cols));
+  VERIFY_IS_EQUAL(map3, MatrixType::Ones(rows,cols));
+  map1 = MatrixType::Random(rows,cols);
+  map2 = map1;
+  map3 = map1;
+  MatrixType ma1 = map1;
+  MatrixType ma2 = map2;
+  MatrixType ma3 = map3;
+  VERIFY_IS_EQUAL(map1, map2);
+  VERIFY_IS_EQUAL(map1, map3);
   VERIFY_IS_EQUAL(ma1, ma2);
-  MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);
   VERIFY_IS_EQUAL(ma1, ma3);
+  VERIFY_IS_EQUAL(ma1, map3);
+  
+  VERIFY_IS_APPROX(s1*map1, s1*map2);
+  VERIFY_IS_APPROX(s1*ma1, s1*ma2);
+  VERIFY_IS_EQUAL(s1*ma1, s1*ma3);
+  VERIFY_IS_APPROX(s1*map1, s1*map3);
+  
+  map2 *= s1;
+  map3 *= s1;
+  VERIFY_IS_APPROX(s1*map1, map2);
+  VERIFY_IS_APPROX(s1*map1, map3);
+  
+  if(size<=256)
+  {
+    VERIFY_IS_EQUAL(map4, MatrixType::Ones(rows,cols));
+    map4 = map1;
+    MatrixType ma4 = map4;
+    VERIFY_IS_EQUAL(map1, map4);
+    VERIFY_IS_EQUAL(ma1, map4);
+    VERIFY_IS_EQUAL(ma1, ma4);
+    VERIFY_IS_APPROX(s1*map1, s1*map4);
+    
+    map4 *= s1;
+    VERIFY_IS_APPROX(s1*map1, map4);
+  }
 
   internal::aligned_delete(array1, size);
   internal::aligned_delete(array2, size);
@@ -75,16 +120,14 @@
 
 template<typename VectorType> void map_static_methods(const VectorType& m)
 {
-  typedef typename VectorType::Index Index;
   typedef typename VectorType::Scalar Scalar;
 
   Index size = m.size();
 
-  // test Map.h
   Scalar* array1 = internal::aligned_new<Scalar>(size);
   Scalar* array2 = internal::aligned_new<Scalar>(size);
   Scalar* array3 = new Scalar[size+1];
-  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
+  Scalar* array3unaligned = internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES == 0 ? array3+1 : array3;
 
   VectorType::MapAligned(array1, size) = VectorType::Random(size);
   VectorType::Map(array2, size) = VectorType::Map(array1, size);
@@ -109,16 +152,15 @@
   // verify that map-to-const don't have LvalueBit
   typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
   VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );
-  VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
+  VERIFY( !(internal::traits<Map<ConstPlainObjectType, AlignedMax> >::Flags & LvalueBit) );
   VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );
-  VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
+  VERIFY( !(Map<ConstPlainObjectType, AlignedMax>::Flags & LvalueBit) );
 }
 
 template<typename Scalar>
 void map_not_aligned_on_scalar()
 {
   typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
-  typedef typename MatrixType::Index Index;
   Index size = 11;
   Scalar* array1 = internal::aligned_new<Scalar>((size+1)*(size+1)+1);
   Scalar* array2 = reinterpret_cast<Scalar*>(sizeof(Scalar)/2+std::size_t(array1));
@@ -142,6 +184,7 @@
     CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
     CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );
     CALL_SUBTEST_2( map_class_vector(Vector4d()) );
+    CALL_SUBTEST_2( map_class_vector(VectorXd(13)) );
     CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );
     CALL_SUBTEST_3( map_class_vector(RowVector4f()) );
     CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );