It's here that template and iterator pattern have to be use to decouple the algorithm/function implementation of the container implementation.
template<class InputIteratorT1, typename InputIteratorT2> void CheckEqualForGivenAccuracy( InputIteratorT1 first_left, InputIteratorT1 last_left, InputIteratorT2 first_right, InputIteratorT2 last_right, double tstEspilon = (double)std::numeric_limits<typename InputIteratorT1::value_type>::epsilon(), std::ostream& stream = null_ostream )
{
CHECK(std::distance(first_left, last_left) && std::distance(first_right, last_right));
stream << std::string(__FUNCTION__) << " of " << std::distance(first_left, last_left) << " elements with epsilon = " << tstEspilon << std::endl;
unsigned int nb_error = 0;
double sum_abs_diff = 0.0;
double max_diff = 0.0;
double min_diff = 0.0;
while(first_left != last_left)
{
if(fabs((double)*first_left - (double)*first_right) > tstEspilon)
{
nb_error++;
double diff = (double)*first_left - (double)*first_right;
sum_abs_diff += std::abs<double>(diff);
max_diff = std::max(max_diff, diff);
min_diff = std::min(min_diff, diff);
}
first_left++; first_right++;
}
if(nb_error > 0)
{
stream << std::string(__FUNCTION__) << " error= " << nb_error << " sum_abs_diff = " << sum_abs_diff << " max_diff = " << max_diff << " min_diff = " << min_diff << std::endl;
}
CHECK(nb_error == 0);
}
That implementation is range-based, the 2 data type can be different ((internally a promotion to double is made), and we have 2 optional parameters, one to specify the error limit and the second to log message. By default the error limit use the standard epsilon value from the numeric type_trait class, and the ostream my implementation of a /dev/null output.
Aucun commentaire :
Enregistrer un commentaire