Files
FastDeploy/third_party/eigen/test/AnnoyingScalar.h
Jack Zhou 355382ad63 Move eigen to third party (#282)
* remove useless statement

* Add eigen to third_party dir

* remove reducdant lines
2022-09-26 19:24:02 +08:00

209 lines
5.4 KiB
C++

// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011-2018 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef EIGEN_TEST_ANNOYING_SCALAR_H
#define EIGEN_TEST_ANNOYING_SCALAR_H
#include <ostream>
#if EIGEN_COMP_GNUC
#pragma GCC diagnostic ignored "-Wshadow"
#endif
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
struct my_exception {
my_exception() {}
~my_exception() {}
};
#endif
// An AnnoyingScalar is a pseudo scalar type that:
// - can randomly through an exception in operator +
// - randomly allocate on the heap or initialize a reference to itself making it
// non trivially copyable, nor movable, nor relocatable.
class AnnoyingScalar {
public:
AnnoyingScalar() {
init();
*v = 0;
}
AnnoyingScalar(long double _v) {
init();
*v = _v;
}
AnnoyingScalar(double _v) {
init();
*v = _v;
}
AnnoyingScalar(float _v) {
init();
*v = _v;
}
AnnoyingScalar(int _v) {
init();
*v = _v;
}
AnnoyingScalar(long _v) {
init();
*v = _v;
}
#if EIGEN_HAS_CXX11
AnnoyingScalar(long long _v) {
init();
*v = _v;
}
#endif
AnnoyingScalar(const AnnoyingScalar& other) {
init();
*v = *(other.v);
}
~AnnoyingScalar() {
if (v != &data) delete v;
instances--;
}
void init() {
if (internal::random<bool>())
v = new float;
else
v = &data;
instances++;
}
AnnoyingScalar operator+(const AnnoyingScalar& other) const {
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
countdown--;
if (countdown <= 0 && !dont_throw) throw my_exception();
#endif
return AnnoyingScalar(*v + *other.v);
}
AnnoyingScalar operator-() const { return AnnoyingScalar(-*v); }
AnnoyingScalar operator-(const AnnoyingScalar& other) const {
return AnnoyingScalar(*v - *other.v);
}
AnnoyingScalar operator*(const AnnoyingScalar& other) const {
return AnnoyingScalar((*v) * (*other.v));
}
AnnoyingScalar operator/(const AnnoyingScalar& other) const {
return AnnoyingScalar((*v) / (*other.v));
}
AnnoyingScalar& operator+=(const AnnoyingScalar& other) {
*v += *other.v;
return *this;
}
AnnoyingScalar& operator-=(const AnnoyingScalar& other) {
*v -= *other.v;
return *this;
}
AnnoyingScalar& operator*=(const AnnoyingScalar& other) {
*v *= *other.v;
return *this;
}
AnnoyingScalar& operator/=(const AnnoyingScalar& other) {
*v /= *other.v;
return *this;
}
AnnoyingScalar& operator=(const AnnoyingScalar& other) {
*v = *other.v;
return *this;
}
bool operator==(const AnnoyingScalar& other) const { return *v == *other.v; }
bool operator!=(const AnnoyingScalar& other) const { return *v != *other.v; }
bool operator<=(const AnnoyingScalar& other) const { return *v <= *other.v; }
bool operator<(const AnnoyingScalar& other) const { return *v < *other.v; }
bool operator>=(const AnnoyingScalar& other) const { return *v >= *other.v; }
bool operator>(const AnnoyingScalar& other) const { return *v > *other.v; }
float* v;
float data;
static int instances;
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
static int countdown;
static bool dont_throw;
#endif
};
AnnoyingScalar real(const AnnoyingScalar& x) { return x; }
AnnoyingScalar imag(const AnnoyingScalar&) { return 0; }
AnnoyingScalar conj(const AnnoyingScalar& x) { return x; }
AnnoyingScalar sqrt(const AnnoyingScalar& x) { return std::sqrt(*x.v); }
AnnoyingScalar abs(const AnnoyingScalar& x) { return std::abs(*x.v); }
AnnoyingScalar cos(const AnnoyingScalar& x) { return std::cos(*x.v); }
AnnoyingScalar sin(const AnnoyingScalar& x) { return std::sin(*x.v); }
AnnoyingScalar acos(const AnnoyingScalar& x) { return std::acos(*x.v); }
AnnoyingScalar atan2(const AnnoyingScalar& y, const AnnoyingScalar& x) {
return std::atan2(*y.v, *x.v);
}
std::ostream& operator<<(std::ostream& stream, const AnnoyingScalar& x) {
stream << (*(x.v));
return stream;
}
int AnnoyingScalar::instances = 0;
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
int AnnoyingScalar::countdown = 0;
bool AnnoyingScalar::dont_throw = false;
#endif
namespace Eigen {
template <>
struct NumTraits<AnnoyingScalar> : NumTraits<float> {
enum { RequireInitialization = true };
typedef AnnoyingScalar Real;
typedef AnnoyingScalar Nested;
typedef AnnoyingScalar Literal;
typedef AnnoyingScalar NonInteger;
};
template <>
inline AnnoyingScalar test_precision<AnnoyingScalar>() {
return test_precision<float>();
}
namespace internal {
template <>
double cast(const AnnoyingScalar& x) {
return double(*x.v);
}
template <>
float cast(const AnnoyingScalar& x) {
return *x.v;
}
}
}
AnnoyingScalar get_test_precision(const AnnoyingScalar&) {
return Eigen::test_precision<AnnoyingScalar>();
}
AnnoyingScalar test_relative_error(const AnnoyingScalar& a,
const AnnoyingScalar& b) {
return test_relative_error(*a.v, *b.v);
}
inline bool test_isApprox(const AnnoyingScalar& a, const AnnoyingScalar& b) {
return internal::isApprox(*a.v, *b.v, test_precision<float>());
}
inline bool test_isMuchSmallerThan(const AnnoyingScalar& a,
const AnnoyingScalar& b) {
return test_isMuchSmallerThan(*a.v, *b.v);
}
#endif // EIGEN_TEST_ANNOYING_SCALAR_H