xref: /aosp_15_r20/external/eigen/test/AnnoyingScalar.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2011-2018 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li //
6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9*bf2c3715SXin Li 
10*bf2c3715SXin Li #ifndef EIGEN_TEST_ANNOYING_SCALAR_H
11*bf2c3715SXin Li #define EIGEN_TEST_ANNOYING_SCALAR_H
12*bf2c3715SXin Li 
13*bf2c3715SXin Li #include <ostream>
14*bf2c3715SXin Li 
15*bf2c3715SXin Li #if EIGEN_COMP_GNUC
16*bf2c3715SXin Li #pragma GCC diagnostic ignored "-Wshadow"
17*bf2c3715SXin Li #endif
18*bf2c3715SXin Li 
19*bf2c3715SXin Li #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
20*bf2c3715SXin Li struct my_exception
21*bf2c3715SXin Li {
my_exceptionmy_exception22*bf2c3715SXin Li   my_exception() {}
~my_exceptionmy_exception23*bf2c3715SXin Li   ~my_exception() {}
24*bf2c3715SXin Li };
25*bf2c3715SXin Li #endif
26*bf2c3715SXin Li 
27*bf2c3715SXin Li // An AnnoyingScalar is a pseudo scalar type that:
28*bf2c3715SXin Li // - can randomly through an exception in operator +
29*bf2c3715SXin Li // - randomly allocate on the heap or initialize a reference to itself making it non trivially copyable, nor movable, nor relocatable.
30*bf2c3715SXin Li 
31*bf2c3715SXin Li class AnnoyingScalar
32*bf2c3715SXin Li {
33*bf2c3715SXin Li   public:
AnnoyingScalar()34*bf2c3715SXin Li     AnnoyingScalar()                { init(); *v = 0;  }
AnnoyingScalar(long double _v)35*bf2c3715SXin Li     AnnoyingScalar(long double _v)  { init(); *v = _v; }
AnnoyingScalar(double _v)36*bf2c3715SXin Li     AnnoyingScalar(double _v)       { init(); *v = _v; }
AnnoyingScalar(float _v)37*bf2c3715SXin Li     AnnoyingScalar(float _v)        { init(); *v = _v; }
AnnoyingScalar(int _v)38*bf2c3715SXin Li     AnnoyingScalar(int _v)          { init(); *v = _v; }
AnnoyingScalar(long _v)39*bf2c3715SXin Li     AnnoyingScalar(long _v)         { init(); *v = _v; }
40*bf2c3715SXin Li     #if EIGEN_HAS_CXX11
AnnoyingScalar(long long _v)41*bf2c3715SXin Li     AnnoyingScalar(long long _v)    { init(); *v = _v; }
42*bf2c3715SXin Li     #endif
AnnoyingScalar(const AnnoyingScalar & other)43*bf2c3715SXin Li     AnnoyingScalar(const AnnoyingScalar& other) { init(); *v = *(other.v); }
~AnnoyingScalar()44*bf2c3715SXin Li     ~AnnoyingScalar() {
45*bf2c3715SXin Li       if(v!=&data)
46*bf2c3715SXin Li         delete v;
47*bf2c3715SXin Li       instances--;
48*bf2c3715SXin Li     }
49*bf2c3715SXin Li 
init()50*bf2c3715SXin Li     void init() {
51*bf2c3715SXin Li       if(internal::random<bool>())
52*bf2c3715SXin Li         v = new float;
53*bf2c3715SXin Li       else
54*bf2c3715SXin Li         v = &data;
55*bf2c3715SXin Li       instances++;
56*bf2c3715SXin Li     }
57*bf2c3715SXin Li 
58*bf2c3715SXin Li     AnnoyingScalar operator+(const AnnoyingScalar& other) const
59*bf2c3715SXin Li     {
60*bf2c3715SXin Li       #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
61*bf2c3715SXin Li       countdown--;
62*bf2c3715SXin Li       if(countdown<=0 && !dont_throw)
63*bf2c3715SXin Li         throw my_exception();
64*bf2c3715SXin Li       #endif
65*bf2c3715SXin Li       return AnnoyingScalar(*v+*other.v);
66*bf2c3715SXin Li     }
67*bf2c3715SXin Li 
68*bf2c3715SXin Li     AnnoyingScalar operator-() const
69*bf2c3715SXin Li     { return AnnoyingScalar(-*v); }
70*bf2c3715SXin Li 
71*bf2c3715SXin Li     AnnoyingScalar operator-(const AnnoyingScalar& other) const
72*bf2c3715SXin Li     { return AnnoyingScalar(*v-*other.v); }
73*bf2c3715SXin Li 
74*bf2c3715SXin Li     AnnoyingScalar operator*(const AnnoyingScalar& other) const
75*bf2c3715SXin Li     { return AnnoyingScalar((*v)*(*other.v)); }
76*bf2c3715SXin Li 
77*bf2c3715SXin Li     AnnoyingScalar operator/(const AnnoyingScalar& other) const
78*bf2c3715SXin Li     { return AnnoyingScalar((*v)/(*other.v)); }
79*bf2c3715SXin Li 
80*bf2c3715SXin Li     AnnoyingScalar& operator+=(const AnnoyingScalar& other) { *v += *other.v; return *this; }
81*bf2c3715SXin Li     AnnoyingScalar& operator-=(const AnnoyingScalar& other) { *v -= *other.v; return *this; }
82*bf2c3715SXin Li     AnnoyingScalar& operator*=(const AnnoyingScalar& other) { *v *= *other.v; return *this; }
83*bf2c3715SXin Li     AnnoyingScalar& operator/=(const AnnoyingScalar& other) { *v /= *other.v; return *this; }
84*bf2c3715SXin Li     AnnoyingScalar& operator= (const AnnoyingScalar& other) { *v  = *other.v; return *this; }
85*bf2c3715SXin Li 
86*bf2c3715SXin Li     bool operator==(const AnnoyingScalar& other) const { return *v == *other.v; }
87*bf2c3715SXin Li     bool operator!=(const AnnoyingScalar& other) const { return *v != *other.v; }
88*bf2c3715SXin Li     bool operator<=(const AnnoyingScalar& other) const { return *v <= *other.v; }
89*bf2c3715SXin Li     bool operator< (const AnnoyingScalar& other) const { return *v <  *other.v; }
90*bf2c3715SXin Li     bool operator>=(const AnnoyingScalar& other) const { return *v >= *other.v; }
91*bf2c3715SXin Li     bool operator> (const AnnoyingScalar& other) const { return *v >  *other.v; }
92*bf2c3715SXin Li 
93*bf2c3715SXin Li     float* v;
94*bf2c3715SXin Li     float data;
95*bf2c3715SXin Li     static int instances;
96*bf2c3715SXin Li #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
97*bf2c3715SXin Li     static int countdown;
98*bf2c3715SXin Li     static bool dont_throw;
99*bf2c3715SXin Li #endif
100*bf2c3715SXin Li };
101*bf2c3715SXin Li 
real(const AnnoyingScalar & x)102*bf2c3715SXin Li AnnoyingScalar real(const AnnoyingScalar &x) { return x; }
imag(const AnnoyingScalar &)103*bf2c3715SXin Li AnnoyingScalar imag(const AnnoyingScalar & ) { return 0; }
conj(const AnnoyingScalar & x)104*bf2c3715SXin Li AnnoyingScalar conj(const AnnoyingScalar &x) { return x; }
sqrt(const AnnoyingScalar & x)105*bf2c3715SXin Li AnnoyingScalar sqrt(const AnnoyingScalar &x) { return std::sqrt(*x.v); }
abs(const AnnoyingScalar & x)106*bf2c3715SXin Li AnnoyingScalar abs (const AnnoyingScalar &x) { return std::abs(*x.v); }
cos(const AnnoyingScalar & x)107*bf2c3715SXin Li AnnoyingScalar cos (const AnnoyingScalar &x) { return std::cos(*x.v); }
sin(const AnnoyingScalar & x)108*bf2c3715SXin Li AnnoyingScalar sin (const AnnoyingScalar &x) { return std::sin(*x.v); }
acos(const AnnoyingScalar & x)109*bf2c3715SXin Li AnnoyingScalar acos(const AnnoyingScalar &x) { return std::acos(*x.v); }
atan2(const AnnoyingScalar & y,const AnnoyingScalar & x)110*bf2c3715SXin Li AnnoyingScalar atan2(const AnnoyingScalar &y,const AnnoyingScalar &x) { return std::atan2(*y.v,*x.v); }
111*bf2c3715SXin Li 
112*bf2c3715SXin Li std::ostream& operator<<(std::ostream& stream,const AnnoyingScalar& x) {
113*bf2c3715SXin Li   stream << (*(x.v));
114*bf2c3715SXin Li   return stream;
115*bf2c3715SXin Li }
116*bf2c3715SXin Li 
117*bf2c3715SXin Li int AnnoyingScalar::instances = 0;
118*bf2c3715SXin Li 
119*bf2c3715SXin Li #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
120*bf2c3715SXin Li int AnnoyingScalar::countdown = 0;
121*bf2c3715SXin Li bool AnnoyingScalar::dont_throw = false;
122*bf2c3715SXin Li #endif
123*bf2c3715SXin Li 
124*bf2c3715SXin Li namespace Eigen {
125*bf2c3715SXin Li template<>
126*bf2c3715SXin Li struct NumTraits<AnnoyingScalar> : NumTraits<float>
127*bf2c3715SXin Li {
128*bf2c3715SXin Li   enum {
129*bf2c3715SXin Li     RequireInitialization = 1,
130*bf2c3715SXin Li   };
131*bf2c3715SXin Li   typedef AnnoyingScalar Real;
132*bf2c3715SXin Li   typedef AnnoyingScalar Nested;
133*bf2c3715SXin Li   typedef AnnoyingScalar Literal;
134*bf2c3715SXin Li   typedef AnnoyingScalar NonInteger;
135*bf2c3715SXin Li };
136*bf2c3715SXin Li 
137*bf2c3715SXin Li template<> inline AnnoyingScalar test_precision<AnnoyingScalar>() { return test_precision<float>(); }
138*bf2c3715SXin Li 
139*bf2c3715SXin Li namespace numext {
140*bf2c3715SXin Li template<>
141*bf2c3715SXin Li EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
142*bf2c3715SXin Li bool (isfinite)(const AnnoyingScalar& x) {
143*bf2c3715SXin Li   return (numext::isfinite)(*x.v);
144*bf2c3715SXin Li }
145*bf2c3715SXin Li }
146*bf2c3715SXin Li 
147*bf2c3715SXin Li namespace internal {
148*bf2c3715SXin Li   template<> EIGEN_STRONG_INLINE double cast(const AnnoyingScalar& x) { return double(*x.v); }
149*bf2c3715SXin Li   template<> EIGEN_STRONG_INLINE float  cast(const AnnoyingScalar& x) { return *x.v; }
150*bf2c3715SXin Li }
151*bf2c3715SXin Li }  // namespace Eigen
152*bf2c3715SXin Li 
153*bf2c3715SXin Li AnnoyingScalar get_test_precision(const AnnoyingScalar&)
154*bf2c3715SXin Li { return Eigen::test_precision<AnnoyingScalar>(); }
155*bf2c3715SXin Li 
156*bf2c3715SXin Li AnnoyingScalar test_relative_error(const AnnoyingScalar &a, const AnnoyingScalar &b)
157*bf2c3715SXin Li { return test_relative_error(*a.v, *b.v); }
158*bf2c3715SXin Li 
159*bf2c3715SXin Li inline bool test_isApprox(const AnnoyingScalar &a, const AnnoyingScalar &b)
160*bf2c3715SXin Li { return internal::isApprox(*a.v, *b.v, test_precision<float>()); }
161*bf2c3715SXin Li 
162*bf2c3715SXin Li inline bool test_isMuchSmallerThan(const AnnoyingScalar &a, const AnnoyingScalar &b)
163*bf2c3715SXin Li { return test_isMuchSmallerThan(*a.v, *b.v); }
164*bf2c3715SXin Li 
165*bf2c3715SXin Li #endif // EIGEN_TEST_ANNOYING_SCALAR_H
166