1 #pragma once 2 3 /// \file Approx.h 4 /// \brief Helper wrapper that allows to check whether two values are equal to some given accuracy. 5 /// \author Pavel Sevecek (sevecek at sirrah.troja.mff.cuni.cz) 6 /// \date 2016-2021 7 8 #include "objects/geometry/TracelessTensor.h" 9 10 NAMESPACE_SPH_BEGIN 11 12 /// This is more or less stolen from Catch unit-testing framework. 13 template <typename Type> 14 class Approx { 15 private: 16 Float epsilon; 17 Type value; 18 19 public: Approx(const Type value)20 INLINE explicit Approx(const Type value) 21 : epsilon(EPS) 22 , value(value) {} 23 operator()24 INLINE Approx operator()(const Type& value) { 25 Approx approx(value); 26 approx.setEpsilon(epsilon); 27 return approx; 28 } 29 30 INLINE friend bool operator==(const Type& lhs, const Approx& rhs) { 31 return almostEqual(lhs, rhs.value, rhs.epsilon); 32 } 33 34 INLINE friend bool operator==(const Approx& lhs, const Type& rhs) { 35 return operator==(rhs, lhs); 36 } 37 38 INLINE friend bool operator!=(const Type& lhs, const Approx& rhs) { 39 return !operator==(lhs, rhs); 40 } 41 42 INLINE friend bool operator!=(const Approx& lhs, const Type& rhs) { 43 return !operator==(rhs, lhs); 44 } 45 setEpsilon(const Float newEps)46 INLINE Approx& setEpsilon(const Float newEps) { 47 epsilon = newEps; 48 return *this; 49 } 50 51 friend std::ostream& operator<<(std::ostream& stream, const Approx& approx) { 52 stream << "~" << approx.value << " (eps = " << approx.epsilon << ")"; 53 return stream; 54 } 55 }; 56 57 /// We have to wait till c++17 for type deduction in constructors ... 58 template <typename Type> 59 Approx<Type> approx(const Type& value, const Float eps = EPS) { 60 return Approx<Type>(value).setEpsilon(eps); 61 } 62 63 64 NAMESPACE_SPH_END 65