Ariles
compare.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2017-2020 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 
11 #pragma once
12 
13 #include <boost/math/special_functions.hpp>
14 #include "common.h"
15 
16 /**
17 @defgroup compare Compare
18 
19 @brief Class comparison.
20 */
21 
22 namespace ariles2
23 {
24  /// @ingroup compare
25  namespace compare
26  {
28  {
29  public:
33  bool nan_equal_;
34  bool inf_equal_;
35  /// @todo continue on failure.
36 
37 
38  public:
39  Parameters(const bool override_parameters = true) : visitor::Parameters(override_parameters)
40  {
41  setDefaults();
42  }
43 
44 
45  void setDefaults()
46  {
47  double_tolerance_ = 1e-12;
48  float_tolerance_ = 1e-8;
49  compare_number_of_entries_ = false;
50 
51  nan_equal_ = true;
52  inf_equal_ = true;
53  }
54 
55 
56  template <typename t_Scalar>
57  t_Scalar getTolerance(const typename ARILES2_IS_FLOATING_POINT_ENABLER_TYPE(t_Scalar) = NULL) const;
58 
59  template <class t_Complex>
60  typename t_Complex::value_type getTolerance() const
61  {
62  return (getTolerance<typename t_Complex::value_type>());
63  }
64  };
65 
66 
67  class ARILES2_VISIBILITY_ATTRIBUTE Visitor : public visitor::Base<visitor::Visitor, compare::Parameters, bool>
68  {
69  public:
71 
72 
73  public:
74  bool equal_;
75  std::vector<std::string> backtrace_;
76 
77 
78  public:
80 
81  template <class t_Ariles>
82  const Parameters &getParameters(const t_Ariles &ariles_class) const
83  {
84  return (ariles_class.arilesGetParameters(*this));
85  }
86 
87 
88  template <class t_Left, class t_Right>
89  bool visit(const t_Left &left, const t_Right &right, const std::string &name, const Parameters &param)
90  {
91  ARILES2_TRACE_FUNCTION;
92  try
93  {
94  equal_ = true;
95  this->visitMapEntry(left, right, name, param);
96  if (false == equal_)
97  {
98  backtrace_.push_back(name);
99  }
100  }
101  catch (std::exception &e)
102  {
103  backtrace_.push_back(e.what());
104  equal_ = false;
105  }
106  return (equal_);
107  }
108 
109 
110  template <typename t_Scalar>
111  static bool compareFloats(const t_Scalar left, const t_Scalar right, const Parameters &param)
112  {
113  if (boost::math::isnan(left))
114  {
115  if (boost::math::isnan(right))
116  {
117  return (param.nan_equal_);
118  }
119  else
120  {
121  return (false);
122  }
123  }
124 
125  if (boost::math::isinf(left))
126  {
127  if (boost::math::isinf(right))
128  {
129  if (((left > 0) && (right > 0)) || ((left < 0) && (right < 0)))
130  {
131  return (param.inf_equal_);
132  }
133  }
134  return (false);
135  }
136  return (std::abs(left - right)
137  <= ((std::abs(left) < std::abs(right) ? std::abs(right) : std::abs(left))
138  * param.double_tolerance_));
139  }
140 
141 
142  template <class t_Left, class t_Right>
144  const t_Left &left,
145  const t_Right &right,
146  const std::string &name,
147  const Parameters &param)
148  {
149  ARILES2_TRACE_FUNCTION;
150  ARILES2_TRACE_VALUE(name);
151  ARILES2_TRACE_TYPE(left);
152  ARILES2_TRACE_TYPE(right);
153 
154  const bool equal_check = this->equal_;
155  apply_compare(*this, left, right, param);
156  if (false == this->equal_ and equal_check != this->equal_)
157  {
158  backtrace_.push_back(name);
159  }
160  }
161  };
162 
163 
164  template <>
165  inline double Visitor::Parameters::getTolerance<double>(
166  const ARILES2_IS_FLOATING_POINT_ENABLER_TYPE(double)) const
167  {
168  return (double_tolerance_);
169  }
170 
171  template <>
172  inline float Visitor::Parameters::getTolerance<float>(const ARILES2_IS_FLOATING_POINT_ENABLER_TYPE(float)) const
173  {
174  return (float_tolerance_);
175  }
176 
177 
179  {
180  };
181 
182 
183 #define ARILES2_NAMED_ENTRY_compare(v, entry, name) visitor.visitMapEntry(entry, other.entry, #name, parameters);
184 #define ARILES2_PARENT_compare(v, entry) entry::arilesVisit(visitor, other, parameters);
185 
186 #define ARILES2_VISIT_compare \
187  template <class t_Other> \
188  void arilesVisit( \
189  ariles2::compare::Visitor &visitor, \
190  const t_Other &other, \
191  const typename ariles2::compare::Visitor::Parameters &parameters) const \
192  { \
193  ARILES2_UNUSED_ARG(visitor); \
194  ARILES2_UNUSED_ARG(other); \
195  ARILES2_UNUSED_ARG(parameters); \
196  ARILES2_TRACE_FUNCTION; \
197  ARILES2_ENTRIES(compare) \
198  }
199 
200 #define ARILES2_METHODS_compare \
201  const ariles2::compare::Visitor::Parameters &arilesGetParameters(const ariles2::compare::Visitor &visitor) const \
202  { \
203  ARILES2_TRACE_FUNCTION; \
204  return (visitor.getDefaultParameters()); \
205  }
206 #define ARILES2_BASE_METHODS_compare
207  } // namespace compare
208 
209 
210  /// @ingroup compare
212 } // namespace ariles2
ariles2::compare::Parameters::nan_equal_
bool nan_equal_
Definition: compare.h:33
ariles2
Definition: basic.h:16
ariles2::compare::Parameters::compare_number_of_entries_
bool compare_number_of_entries_
Definition: compare.h:32
ariles2::visitor::Base
Definition: common.h:50
ariles2::compare::Visitor::Parameters
compare::Parameters Parameters
Definition: compare.h:70
ariles2::compare::Visitor
Definition: compare.h:67
ariles2::compare::Visitor::visitMapEntry
void visitMapEntry(const t_Left &left, const t_Right &right, const std::string &name, const Parameters &param)
Definition: compare.h:143
ARILES2_IS_FLOATING_POINT_ENABLER_TYPE
#define ARILES2_IS_FLOATING_POINT_ENABLER_TYPE(Real)
Definition: helpers.h:55
ariles2::compare::Visitor::compareFloats
static bool compareFloats(const t_Scalar left, const t_Scalar right, const Parameters &param)
Definition: compare.h:111
ariles2::Compare
compare::Visitor Compare
Definition: compare.h:211
ariles2::compare::Parameters
Definition: compare.h:27
ariles2::compare::Visitor::backtrace_
std::vector< std::string > backtrace_
Definition: compare.h:75
common.h
ariles2::compare::apply_compare
void ARILES2_VISIBILITY_ATTRIBUTE apply_compare(t_Visitor &visitor, const t_Left &left, const t_Right &right, const typename t_Visitor::Parameters &param, ARILES2_IS_BASE_ENABLER(ariles2::Ariles, t_Left))
Definition: basic.h:146
ariles2::compare::Visitor::getParameters
const Parameters & getParameters(const t_Ariles &ariles_class) const
Definition: compare.h:82
ARILES2_VISIBILITY_ATTRIBUTE
#define ARILES2_VISIBILITY_ATTRIBUTE
Definition: helpers.h:138
ariles2::visitor::Parameters
Definition: common.h:20
ariles2::compare::Parameters::double_tolerance_
double double_tolerance_
Definition: compare.h:31
ariles2::compare::Parameters::setDefaults
void setDefaults()
Definition: compare.h:45
ariles2::compare::Parameters::inf_equal_
bool inf_equal_
Definition: compare.h:34
ariles2::compare::Parameters::getTolerance
t_Complex::value_type getTolerance() const
Definition: compare.h:60
ariles2::compare::Visitor::visit
bool visit(const t_Left &left, const t_Right &right, const std::string &name, const Parameters &param)
Definition: compare.h:89
ariles2::compare::Parameters::float_tolerance_
double float_tolerance_
Definition: compare.h:30
ariles2::compare::Parameters::Parameters
Parameters(const bool override_parameters=true)
Definition: compare.h:39
ariles2::compare::Visitor::equal_
bool equal_
Definition: compare.h:74
ariles2::compare::Base
Definition: compare.h:178