AnnoyingScalar.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2011-2018 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 #ifndef EIGEN_TEST_ANNOYING_SCALAR_H
11 #define EIGEN_TEST_ANNOYING_SCALAR_H
12 
13 #include <ostream>
14 
15 #if EIGEN_COMP_GNUC
16 #pragma GCC diagnostic ignored "-Wshadow"
17 #endif
18 
19 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
20 struct my_exception {
23 };
24 #endif
25 
26 // An AnnoyingScalar is a pseudo scalar type that:
27 // - can randomly through an exception in operator +
28 // - randomly allocate on the heap or initialize a reference to itself making it non trivially copyable, nor movable,
29 // nor relocatable.
30 
32  public:
34  init();
35  *v = 0;
36  }
37  AnnoyingScalar(long double _v) {
38  init();
39  *v = static_cast<float>(_v);
40  }
41  AnnoyingScalar(double _v) {
42  init();
43  *v = static_cast<float>(_v);
44  }
45  AnnoyingScalar(float _v) {
46  init();
47  *v = _v;
48  }
49  AnnoyingScalar(int _v) {
50  init();
51  *v = static_cast<float>(_v);
52  }
53  AnnoyingScalar(long _v) {
54  init();
55  *v = static_cast<float>(_v);
56  }
57  AnnoyingScalar(long long _v) {
58  init();
59  *v = static_cast<float>(_v);
60  }
62  init();
63  *v = *(other.v);
64  }
66  if (v != &data) delete v;
67  instances--;
68  }
69 
70  void init() {
71  if (internal::random<bool>())
72  v = new float;
73  else
74  v = &data;
75  instances++;
76  }
77 
78  AnnoyingScalar operator+(const AnnoyingScalar& other) const {
79 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
80  countdown--;
81  if (countdown <= 0 && !dont_throw) throw my_exception();
82 #endif
83  return AnnoyingScalar(*v + *other.v);
84  }
85 
86  AnnoyingScalar operator-() const { return AnnoyingScalar(-*v); }
87 
88  AnnoyingScalar operator-(const AnnoyingScalar& other) const { return AnnoyingScalar(*v - *other.v); }
89 
90  AnnoyingScalar operator*(const AnnoyingScalar& other) const { return AnnoyingScalar((*v) * (*other.v)); }
91 
92  AnnoyingScalar operator/(const AnnoyingScalar& other) const { return AnnoyingScalar((*v) / (*other.v)); }
93 
95  *v += *other.v;
96  return *this;
97  }
99  *v -= *other.v;
100  return *this;
101  }
103  *v *= *other.v;
104  return *this;
105  }
107  *v /= *other.v;
108  return *this;
109  }
111  *v = *other.v;
112  return *this;
113  }
114 
115  bool operator==(const AnnoyingScalar& other) const { return numext::equal_strict(*v, *other.v); }
116  bool operator!=(const AnnoyingScalar& other) const { return numext::not_equal_strict(*v, *other.v); }
117  bool operator<=(const AnnoyingScalar& other) const { return *v <= *other.v; }
118  bool operator<(const AnnoyingScalar& other) const { return *v < *other.v; }
119  bool operator>=(const AnnoyingScalar& other) const { return *v >= *other.v; }
120  bool operator>(const AnnoyingScalar& other) const { return *v > *other.v; }
121 
122  float* v;
123  float data;
124  static int instances;
125 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
126  static int countdown;
127  static bool dont_throw;
128 #endif
129 };
130 
131 AnnoyingScalar real(const AnnoyingScalar& x) { return x; }
132 AnnoyingScalar imag(const AnnoyingScalar&) { return 0; }
133 AnnoyingScalar conj(const AnnoyingScalar& x) { return x; }
135 AnnoyingScalar abs(const AnnoyingScalar& x) { return std::abs(*x.v); }
136 AnnoyingScalar cos(const AnnoyingScalar& x) { return std::cos(*x.v); }
137 AnnoyingScalar sin(const AnnoyingScalar& x) { return std::sin(*x.v); }
139 AnnoyingScalar atan2(const AnnoyingScalar& y, const AnnoyingScalar& x) { return std::atan2(*y.v, *x.v); }
140 
141 std::ostream& operator<<(std::ostream& stream, const AnnoyingScalar& x) {
142  stream << (*(x.v));
143  return stream;
144 }
145 
147 
148 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
150 bool AnnoyingScalar::dont_throw = false;
151 #endif
152 
153 namespace Eigen {
154 template <>
156  enum {
158  };
163 };
164 
165 template <>
167  return test_precision<float>();
168 }
169 
170 namespace numext {
171 template <>
173  return (numext::isfinite)(*x.v);
174 }
175 } // namespace numext
176 
177 namespace internal {
178 template <>
180  return double(*x.v);
181 }
182 template <>
184  return *x.v;
185 }
186 
187 } // namespace internal
188 } // namespace Eigen
189 
191 
193  return test_relative_error(*a.v, *b.v);
194 }
195 
196 inline bool test_isApprox(const AnnoyingScalar& a, const AnnoyingScalar& b) {
197  return internal::isApprox(*a.v, *b.v, test_precision<float>());
198 }
199 
201  return test_isMuchSmallerThan(*a.v, *b.v);
202 }
203 
204 #endif // EIGEN_TEST_ANNOYING_SCALAR_H
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
bool test_isApprox(const AnnoyingScalar &a, const AnnoyingScalar &b)
Definition: AnnoyingScalar.h:196
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar atan2(const AnnoyingScalar &y, const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:139
AnnoyingScalar get_test_precision(const AnnoyingScalar &)
Definition: AnnoyingScalar.h:190
AnnoyingScalar acos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:138
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
AnnoyingScalar conj(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:133
bool test_isMuchSmallerThan(const AnnoyingScalar &a, const AnnoyingScalar &b)
Definition: AnnoyingScalar.h:200
AnnoyingScalar test_relative_error(const AnnoyingScalar &a, const AnnoyingScalar &b)
Definition: AnnoyingScalar.h:192
AnnoyingScalar imag(const AnnoyingScalar &)
Definition: AnnoyingScalar.h:132
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
AnnoyingScalar real(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:131
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:845
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
Scalar * b
Definition: benchVecAdd.cpp:17
Definition: AnnoyingScalar.h:31
float data
Definition: AnnoyingScalar.h:123
static int instances
Definition: AnnoyingScalar.h:124
AnnoyingScalar & operator=(const AnnoyingScalar &other)
Definition: AnnoyingScalar.h:110
AnnoyingScalar operator/(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:92
AnnoyingScalar operator+(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:78
AnnoyingScalar()
Definition: AnnoyingScalar.h:33
bool operator>(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:120
AnnoyingScalar(double _v)
Definition: AnnoyingScalar.h:41
void init()
Definition: AnnoyingScalar.h:70
~AnnoyingScalar()
Definition: AnnoyingScalar.h:65
AnnoyingScalar & operator+=(const AnnoyingScalar &other)
Definition: AnnoyingScalar.h:94
float * v
Definition: AnnoyingScalar.h:122
AnnoyingScalar(long _v)
Definition: AnnoyingScalar.h:53
AnnoyingScalar & operator-=(const AnnoyingScalar &other)
Definition: AnnoyingScalar.h:98
AnnoyingScalar(float _v)
Definition: AnnoyingScalar.h:45
AnnoyingScalar(int _v)
Definition: AnnoyingScalar.h:49
AnnoyingScalar(long double _v)
Definition: AnnoyingScalar.h:37
static int countdown
Definition: AnnoyingScalar.h:126
AnnoyingScalar operator-() const
Definition: AnnoyingScalar.h:86
AnnoyingScalar & operator/=(const AnnoyingScalar &other)
Definition: AnnoyingScalar.h:106
bool operator==(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:115
AnnoyingScalar(long long _v)
Definition: AnnoyingScalar.h:57
AnnoyingScalar & operator*=(const AnnoyingScalar &other)
Definition: AnnoyingScalar.h:102
static bool dont_throw
Definition: AnnoyingScalar.h:127
AnnoyingScalar(const AnnoyingScalar &other)
Definition: AnnoyingScalar.h:61
bool operator<=(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:117
bool operator<(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:118
bool operator>=(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:119
AnnoyingScalar operator-(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:88
AnnoyingScalar operator*(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:90
bool operator!=(const AnnoyingScalar &other) const
Definition: AnnoyingScalar.h:116
std::ostream & operator<<(std::ostream &s, const DenseBase< Derived > &m)
Definition: IO.h:222
Scalar * y
Definition: level1_cplx_impl.h:128
const Scalar * a
Definition: level2_cplx_impl.h:32
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition: MathFunctions.h:1923
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Definition: MathFunctions.h:362
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X &x, const Y &y)
Definition: Meta.h:571
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool() isfinite(const Eigen::bfloat16 &h)
Definition: BFloat16.h:752
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const X &x, const Y &y)
Definition: Meta.h:606
EIGEN_DEVICE_FUNC const Scalar & x
Definition: SpecialFunctionsImpl.h:2024
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
float test_precision< float >()
Definition: main.h:416
AnnoyingScalar test_precision< AnnoyingScalar >()
Definition: AnnoyingScalar.h:166
Definition: Eigen_Colamd.h:49
list x
Definition: plotDoE.py:28
float test_precision< float >()
Definition: spbenchsolver.h:93
@ RequireInitialization
Definition: NumTraits.h:177
AnnoyingScalar NonInteger
Definition: AnnoyingScalar.h:162
AnnoyingScalar Nested
Definition: AnnoyingScalar.h:160
AnnoyingScalar Real
Definition: AnnoyingScalar.h:159
AnnoyingScalar Literal
Definition: AnnoyingScalar.h:161
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: AnnoyingScalar.h:20
~my_exception()
Definition: AnnoyingScalar.h:22
my_exception()
Definition: AnnoyingScalar.h:21