Using Approx on user supplied objects

72 views
Skip to first unread message

Joes Staal

unread,
Jan 5, 2015, 10:39:58 AM1/5/15
to catch...@googlegroups.com
Hi,

I am wondering if it would be difficult to extend Approx in such a way that e.g. a container of elements can be checked, e.g.
std::vector<double> v = {1, 2, 3};
REQUIRE(v == Approx({1, 2, 3});

If any corresponding element would be outside the range of approximately being equal, the test would fail.
It would even be nicer if I could put user supplied object into Approx, e.g.

struct Point
{
  double x;
  double y;
};

Point p = ..;
Point q = ..;

REQUIRE(p == Approx(q));

Would that be possible?

Cheers,

Joes

Joes Staal

unread,
Feb 2, 2015, 5:46:49 AM2/2/15
to catch...@googlegroups.com
Currently I've come up with the following solution, of which I am not very happy.

I've made my own templated Approx class which calls into a templated function approximately_equal, which is undefined and specialized for the types I'd like to use:

 template <typename T> bool approximately_equal(const T& lhs, const T& rhs, double epsilon, double scale)
 
{
 
}


 
template <> bool approximately_equal(double const& lhs, double const& rhs, double epsilon, double scale)
 
{
 
// Thanks to Richard Harris for his help refining this formula
 
return fabs(lhs - rhs) < epsilon * (scale + (std::max)(fabs(lhs), fabs(rhs)));
 
}


 
template <> bool approximately_equal(Point2D const& lhs, Point2D const& rhs, double epsilon, double scale)
 
{
 
return approximately_equal(lhs.x, rhs.x, epsilon, scale) && approximately_equal(lhs.y, rhs.y, epsilon, scale);
 
}


The disadvantage is that I need to supply the type when checking the requirement:

REQUIRE(p == Approx<Point2D>(q));

If I could get rid of having to supply the type, I would be very pleased. But since Approx is a class, I don't see how I could do that. 

Any better options?

Cheers,

Joes

Joes Staal

unread,
Feb 2, 2015, 5:55:02 AM2/2/15
to catch...@googlegroups.com
Of course, one more level of indirection is needed ;-)

 template <typename T> Approx<T> approx(T const& t)
 
{
 
return Approx<T>(t);
 
}

and now I can write:

REQUIRE(p == approx(q));

Now my question is if Phil would be willing to make templated version for Approx with a function that can be specialized for users' own types?

Cheers,

Joes

Kartik Kumar

unread,
Feb 24, 2015, 5:59:05 AM2/24/15
to catch...@googlegroups.com
+1 for including a generalized form of Approx in CATCH so I can eliminate the many for-loops that are littered through my codebase at the moment.
Reply all
Reply to author
Forward
0 new messages