13d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// This file is part of Eigen, a lightweight C++ template library 23d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// for linear algebra. 33d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// 43d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> 53d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// 63d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// This Source Code Form is subject to the terms of the Mozilla 73d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// Public License v. 2.0. If a copy of the MPL was not distributed 83d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 93d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 103d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 113d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// Various sanity tests with exceptions: 123d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// - no memory leak when a custom scalar type trow an exceptions 133d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// - todo: complete the list of tests! 143d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 153d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define EIGEN_STACK_ALLOCATION_LIMIT 100000000 163d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 173d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include "main.h" 183d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 193d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarstruct my_exception 203d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar{ 213d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar my_exception() {} 223d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ~my_exception() {} 233d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar}; 243d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 253d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarclass ScalarWithExceptions 263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar{ 273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar public: 283d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions() { init(); } 293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions(const float& _v) { init(); *v = _v; } 303d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); } 313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ~ScalarWithExceptions() { 323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar delete v; 333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar instances--; 343d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } 353d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 363d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar void init() { 373d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar v = new float; 383d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar instances++; 393d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } 403d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 413d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions operator+(const ScalarWithExceptions& other) const 423d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { 433d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar countdown--; 443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if(countdown<=0) 453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar throw my_exception(); 463d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return ScalarWithExceptions(*v+*other.v); 473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } 483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions operator-(const ScalarWithExceptions& other) const 503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { return ScalarWithExceptions(*v-*other.v); } 513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions operator*(const ScalarWithExceptions& other) const 533d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { return ScalarWithExceptions((*v)*(*other.v)); } 543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 553d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions& operator+=(const ScalarWithExceptions& other) 563d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { *v+=*other.v; return *this; } 573d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions& operator-=(const ScalarWithExceptions& other) 583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { *v-=*other.v; return *this; } 593d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScalarWithExceptions& operator=(const ScalarWithExceptions& other) 603d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { *v = *(other.v); return *this; } 613d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 623d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar bool operator==(const ScalarWithExceptions& other) const 633d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { return *v==*other.v; } 643d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar bool operator!=(const ScalarWithExceptions& other) const 653d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar { return *v!=*other.v; } 663d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 673d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar float* v; 683d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar static int instances; 693d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar static int countdown; 703d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar}; 71 72ScalarWithExceptions real(const ScalarWithExceptions &x) { return x; } 73ScalarWithExceptions imag(const ScalarWithExceptions & ) { return 0; } 74ScalarWithExceptions conj(const ScalarWithExceptions &x) { return x; } 75 76int ScalarWithExceptions::instances = 0; 77int ScalarWithExceptions::countdown = 0; 78 79 80#define CHECK_MEMLEAK(OP) { \ 81 ScalarWithExceptions::countdown = 100; \ 82 int before = ScalarWithExceptions::instances; \ 83 bool exception_thrown = false; \ 84 try { OP; } \ 85 catch (my_exception) { \ 86 exception_thrown = true; \ 87 VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \ 88 } \ 89 VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \ 90 } 91 92void memoryleak() 93{ 94 typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType; 95 typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType; 96 97 { 98 int n = 50; 99 VectorType v0(n), v1(n); 100 MatrixType m0(n,n), m1(n,n), m2(n,n); 101 v0.setOnes(); v1.setOnes(); 102 m0.setOnes(); m1.setOnes(); m2.setOnes(); 103 CHECK_MEMLEAK(v0 = m0 * m1 * v1); 104 CHECK_MEMLEAK(m2 = m0 * m1 * m2); 105 CHECK_MEMLEAK((v0+v1).dot(v0+v1)); 106 } 107 VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \ 108} 109 110void test_exceptions() 111{ 112 CALL_SUBTEST( memoryleak() ); 113} 114