exceptions.cpp revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
1// This file is part of Eigen, a lightweight C++ template library 2// for linear algebra. 3// 4// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> 5// 6// This Source Code Form is subject to the terms of the Mozilla 7// Public License v. 2.0. If a copy of the MPL was not distributed 8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 11// Various sanity tests with exceptions: 12// - no memory leak when a custom scalar type trow an exceptions 13// - todo: complete the list of tests! 14 15#define EIGEN_STACK_ALLOCATION_LIMIT 100000000 16 17#include "main.h" 18 19struct my_exception 20{ 21 my_exception() {} 22 ~my_exception() {} 23}; 24 25class ScalarWithExceptions 26{ 27 public: 28 ScalarWithExceptions() { init(); } 29 ScalarWithExceptions(const float& _v) { init(); *v = _v; } 30 ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); } 31 ~ScalarWithExceptions() { 32 delete v; 33 instances--; 34 } 35 36 void init() { 37 v = new float; 38 instances++; 39 } 40 41 ScalarWithExceptions operator+(const ScalarWithExceptions& other) const 42 { 43 countdown--; 44 if(countdown<=0) 45 throw my_exception(); 46 return ScalarWithExceptions(*v+*other.v); 47 } 48 49 ScalarWithExceptions operator-(const ScalarWithExceptions& other) const 50 { return ScalarWithExceptions(*v-*other.v); } 51 52 ScalarWithExceptions operator*(const ScalarWithExceptions& other) const 53 { return ScalarWithExceptions((*v)*(*other.v)); } 54 55 ScalarWithExceptions& operator+=(const ScalarWithExceptions& other) 56 { *v+=*other.v; return *this; } 57 ScalarWithExceptions& operator-=(const ScalarWithExceptions& other) 58 { *v-=*other.v; return *this; } 59 ScalarWithExceptions& operator=(const ScalarWithExceptions& other) 60 { *v = *(other.v); return *this; } 61 62 bool operator==(const ScalarWithExceptions& other) const 63 { return *v==*other.v; } 64 bool operator!=(const ScalarWithExceptions& other) const 65 { return *v!=*other.v; } 66 67 float* v; 68 static int instances; 69 static int countdown; 70}; 71 72int ScalarWithExceptions::instances = 0; 73int ScalarWithExceptions::countdown = 0; 74 75 76#define CHECK_MEMLEAK(OP) { \ 77 ScalarWithExceptions::countdown = 100; \ 78 int before = ScalarWithExceptions::instances; \ 79 bool exception_thrown = false; \ 80 try { OP; } \ 81 catch (my_exception) { \ 82 exception_thrown = true; \ 83 VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \ 84 } \ 85 VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \ 86 } 87 88void memoryleak() 89{ 90 typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType; 91 typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType; 92 93 { 94 int n = 50; 95 VectorType v0(n), v1(n); 96 MatrixType m0(n,n), m1(n,n), m2(n,n); 97 v0.setOnes(); v1.setOnes(); 98 m0.setOnes(); m1.setOnes(); m2.setOnes(); 99 CHECK_MEMLEAK(v0 = m0 * m1 * v1); 100 CHECK_MEMLEAK(m2 = m0 * m1 * m2); 101 CHECK_MEMLEAK((v0+v1).dot(v0+v1)); 102 } 103 VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \ 104} 105 106void test_exceptions() 107{ 108 CALL_SUBTEST( memoryleak() ); 109} 110