Skip to content

Commit

Permalink
Move Approx's validity checks out of line into cpp file
Browse files Browse the repository at this point in the history
This avoids having to include <stdexcept> in the main include path
and speeds up the compilation if Approx is used with multiple
different types.
  • Loading branch information
horenmar committed Sep 3, 2018
1 parent fcd91c7 commit 84fa76e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 17 deletions.
22 changes: 22 additions & 0 deletions include/internal/catch_approx.cpp
Expand Up @@ -10,6 +10,7 @@

#include <cmath>
#include <limits>
#include <stdexcept>

namespace {

Expand Down Expand Up @@ -54,6 +55,27 @@ namespace Detail {
return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
}

void Approx::setMargin(double margin) {
if (margin < 0) {
throw std::domain_error
("Invalid Approx::margin: " +
Catch::Detail::stringify(margin) +
", Approx::Margin has to be non-negative.");

}
m_margin = margin;
}

void Approx::setEpsilon(double epsilon) {
if (epsilon < 0 || epsilon > 1.0) {
throw std::domain_error
("Invalid Approx::epsilon: " +
Catch::Detail::stringify(epsilon) +
", Approx::epsilon has to be between 0 and 1");
}
m_epsilon = epsilon;
}

} // end namespace Detail

namespace literals {
Expand Down
26 changes: 9 additions & 17 deletions include/internal/catch_approx.h
Expand Up @@ -11,14 +11,19 @@
#include "catch_tostring.h"

#include <type_traits>
#include <stdexcept>

namespace Catch {
namespace Detail {

class Approx {
private:
bool equalityComparisonImpl(double other) const;
// Validates the new margin (margin >= 0)
// out-of-line to avoid including stdexcept in the header
void setMargin(double margin);
// Validates the new epsilon (0 < epsilon < 1)
// out-of-line to avoid including stdexcept in the header
void setEpsilon(double epsilon);

public:
explicit Approx ( double value );
Expand Down Expand Up @@ -85,27 +90,14 @@ namespace Detail {
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& epsilon( T const& newEpsilon ) {
double epsilonAsDouble = static_cast<double>(newEpsilon);
if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
throw std::domain_error
( "Invalid Approx::epsilon: " +
Catch::Detail::stringify( epsilonAsDouble ) +
", Approx::epsilon has to be between 0 and 1" );
}
m_epsilon = epsilonAsDouble;
setEpsilon(epsilonAsDouble);
return *this;
}

template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& margin( T const& newMargin ) {
double marginAsDouble = static_cast<double>(newMargin);
if( marginAsDouble < 0 ) {
throw std::domain_error
( "Invalid Approx::margin: " +
Catch::Detail::stringify( marginAsDouble ) +
", Approx::Margin has to be non-negative." );

}
m_margin = marginAsDouble;
setMargin(marginAsDouble);
return *this;
}

Expand All @@ -124,7 +116,7 @@ namespace Detail {
double m_value;
};
} // end namespace Detail

namespace literals {
Detail::Approx operator "" _a(long double val);
Detail::Approx operator "" _a(unsigned long long val);
Expand Down

0 comments on commit 84fa76e

Please sign in to comment.