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/ctorleak.cpp b/test/ctorleak.cpp
new file mode 100644
index 0000000..c158f5e
--- /dev/null
+++ b/test/ctorleak.cpp
@@ -0,0 +1,69 @@
+#include "main.h"
+
+#include <exception>  // std::exception
+
+struct Foo
+{
+  static Index object_count;
+  static Index object_limit;
+  int dummy;
+
+  Foo()
+  {
+#ifdef EIGEN_EXCEPTIONS
+    // TODO: Is this the correct way to handle this?
+    if (Foo::object_count > Foo::object_limit) { std::cout << "\nThrow!\n"; throw Foo::Fail(); }
+#endif
+	  std::cout << '+';
+    ++Foo::object_count;
+  }
+
+  ~Foo()
+  {
+	  std::cout << '-';
+    --Foo::object_count;
+  }
+
+  class Fail : public std::exception {};
+};
+
+Index Foo::object_count = 0;
+Index Foo::object_limit = 0;
+
+#undef EIGEN_TEST_MAX_SIZE
+#define EIGEN_TEST_MAX_SIZE 3
+
+void test_ctorleak()
+{
+  typedef Matrix<Foo, Dynamic, Dynamic> MatrixX;
+  typedef Matrix<Foo, Dynamic, 1> VectorX;
+  Foo::object_count = 0;
+  for(int i = 0; i < g_repeat; i++) {
+    Index rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);
+    Foo::object_limit = internal::random<Index>(0, rows*cols - 2);
+    std::cout << "object_limit =" << Foo::object_limit << std::endl;
+#ifdef EIGEN_EXCEPTIONS
+    try
+    {
+#endif
+    	std::cout <<       "\nMatrixX m(" << rows << ", " << cols << ");\n";
+      MatrixX m(rows, cols);
+#ifdef EIGEN_EXCEPTIONS
+      VERIFY(false);  // not reached if exceptions are enabled
+    }
+    catch (const Foo::Fail&) { /* ignore */ }
+#endif
+    VERIFY_IS_EQUAL(Index(0), Foo::object_count);
+
+    {
+      Foo::object_limit = (rows+1)*(cols+1);
+      MatrixX A(rows, cols);
+      VERIFY_IS_EQUAL(Foo::object_count, rows*cols);
+      VectorX v=A.row(0);
+      VERIFY_IS_EQUAL(Foo::object_count, (rows+1)*cols);
+      v = A.col(0);
+      VERIFY_IS_EQUAL(Foo::object_count, rows*(cols+1));
+    }
+    VERIFY_IS_EQUAL(Index(0), Foo::object_count);
+  }
+}