aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/ctorleak.cpp
blob: f3f4411c8fb6592ac2563e37809d8c26260d1733 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "main.h"

#include <exception>  // std::exception

struct Foo
{
  static unsigned object_count;
  static unsigned object_limit;
  int dummy;

  Foo()
  {
#ifdef EIGEN_EXCEPTIONS
    // TODO: Is this the correct way to handle this?
    if (Foo::object_count > Foo::object_limit) { throw Foo::Fail(); }
#endif
    ++Foo::object_count;
  }

  ~Foo()
  {
    --Foo::object_count;
  }

  class Fail : public std::exception {};
};

unsigned Foo::object_count = 0;
unsigned Foo::object_limit = 0;

namespace Eigen
{
  template<>
  struct NumTraits<Foo>
  {
    typedef double Real;
    typedef double NonInteger;
    typedef double Nested;
    enum
      {
        IsComplex             =  0,
        IsInteger             =  1,
        ReadCost              = -1,
        AddCost               = -1,
        MulCost               = -1,
        IsSigned              =  1,
        RequireInitialization =  1
      };
    static inline Real epsilon() { return 1.0; }
    static inline Real dummy_epsilon() { return 0.0; }
  };
}

void test_ctorleak()
{
  Foo::object_count = 0;
  Foo::object_limit = internal::random(0, 14 * 92 - 2);
#ifdef EIGEN_EXCEPTIONS
  try
#endif
    {
      Matrix<Foo, Dynamic, Dynamic> m(14, 92);
      eigen_assert(false);  // not reached
    }
#ifdef EIGEN_EXCEPTIONS
  catch (const Foo::Fail&) { /* ignore */ }
#endif
  VERIFY_IS_EQUAL(static_cast<unsigned>(0), Foo::object_count);
}