exceptions.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 
00026 // Various sanity tests with exceptions:
00027 //  - no memory leak when a custom scalar type trow an exceptions
00028 //  - todo: complete the list of tests!
00029 
00030 #define EIGEN_STACK_ALLOCATION_LIMIT 100000000
00031 
00032 #include "main.h"
00033 
00034 struct my_exception
00035 {
00036   my_exception() {}
00037   ~my_exception() {}
00038 };
00039     
00040 class ScalarWithExceptions
00041 {
00042   public:
00043     ScalarWithExceptions() { init(); }
00044     ScalarWithExceptions(const float& _v) { init(); *v = _v; }
00045     ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); }
00046     ~ScalarWithExceptions() {
00047       delete v;
00048       instances--;
00049     }
00050 
00051     void init() {
00052       v = new float;
00053       instances++;
00054     }
00055 
00056     ScalarWithExceptions operator+(const ScalarWithExceptions& other) const
00057     {
00058       countdown--;
00059       if(countdown<=0)
00060         throw my_exception();
00061       return ScalarWithExceptions(*v+*other.v);
00062     }
00063     
00064     ScalarWithExceptions operator-(const ScalarWithExceptions& other) const
00065     { return ScalarWithExceptions(*v-*other.v); }
00066     
00067     ScalarWithExceptions operator*(const ScalarWithExceptions& other) const
00068     { return ScalarWithExceptions((*v)*(*other.v)); }
00069     
00070     ScalarWithExceptions& operator+=(const ScalarWithExceptions& other)
00071     { *v+=*other.v; return *this; }
00072     ScalarWithExceptions& operator-=(const ScalarWithExceptions& other)
00073     { *v-=*other.v; return *this; }
00074     ScalarWithExceptions& operator=(const ScalarWithExceptions& other)
00075     { *v = *(other.v); return *this; }
00076   
00077     bool operator==(const ScalarWithExceptions& other) const
00078     { return *v==*other.v; }
00079     bool operator!=(const ScalarWithExceptions& other) const
00080     { return *v!=*other.v; }
00081     
00082     float* v;
00083     static int instances;
00084     static int countdown;
00085 };
00086 
00087 int ScalarWithExceptions::instances = 0;
00088 int ScalarWithExceptions::countdown = 0;
00089 
00090 
00091 #define CHECK_MEMLEAK(OP) {                                 \
00092     ScalarWithExceptions::countdown = 100;                  \
00093     int before = ScalarWithExceptions::instances;           \
00094     bool exception_thrown = false;                         \
00095     try { OP; }                              \
00096     catch (my_exception) {                                  \
00097       exception_thrown = true;                              \
00098       VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \
00099     } \
00100     VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \
00101   }
00102 
00103 void memoryleak()
00104 {
00105   typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType;
00106   typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType;
00107   
00108   {
00109     int n = 50;
00110     VectorType v0(n), v1(n);
00111     MatrixType m0(n,n), m1(n,n), m2(n,n);
00112     v0.setOnes(); v1.setOnes();
00113     m0.setOnes(); m1.setOnes(); m2.setOnes();
00114     CHECK_MEMLEAK(v0 = m0 * m1 * v1);
00115     CHECK_MEMLEAK(m2 = m0 * m1 * m2);
00116     CHECK_MEMLEAK((v0+v1).dot(v0+v1));
00117   }
00118   VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \
00119 }
00120 
00121 void test_exceptions()
00122 {
00123   CALL_SUBTEST( memoryleak() );
00124 }


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:40