• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2014, Oracle and/or its affiliates.
5 
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10 
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_math_sqrt
13 #endif
14 
15 #include <cmath>
16 #include <iostream>
17 
18 #include <boost/test/included/unit_test.hpp>
19 
20 #include <boost/config.hpp>
21 #include <boost/type_traits/is_fundamental.hpp>
22 
23 #include "number_types.hpp"
24 
25 // important: the include above must precede the include below,
26 // otherwise the test will fail for the custom number type:
27 // custom_with_global_sqrt
28 
29 #include <boost/geometry/util/math.hpp>
30 #include <boost/geometry/algorithms/not_implemented.hpp>
31 
32 #ifdef HAVE_TTMATH
33 #  include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
34 #endif
35 
36 namespace bg = boost::geometry;
37 
38 
39 
40 
41 // call BOOST_CHECK
42 template <typename Argument, bool IsFundamental /* true */>
43 struct check
44 {
45     template <typename Result>
applycheck46     static inline void apply(Argument const& arg, Result const& result)
47     {
48         BOOST_CHECK_CLOSE(static_cast<double>(bg::math::sqrt(arg)),
49                           static_cast<double>(result),
50                           0.00001);
51     }
52 };
53 
54 
55 template <typename Argument>
56 struct check<Argument, false>
57 {
58     template <typename Result>
applycheck59     static inline void apply(Argument const& arg, Result const& result)
60     {
61         Result const tol(0.00001);
62         BOOST_CHECK( bg::math::abs(bg::math::sqrt(arg) - result) < tol );
63     }
64 };
65 
66 
67 
68 
69 
70 
71 // test sqrt return type and value
72 template
73 <
74     typename Argument,
75     typename ExpectedResult,
76     typename Result = typename bg::math::detail::square_root
77         <
78             Argument
79         >::return_type,
80     bool IsFundamental = boost::is_fundamental<Argument>::value
81 >
82 struct check_sqrt
83     : bg::not_implemented<Argument, Result, ExpectedResult>
84 {};
85 
86 
87 template <typename Argument, typename Result, bool IsFundamental>
88 struct check_sqrt<Argument, Result, Result, IsFundamental>
89 {
applycheck_sqrt90     static inline void apply(Argument const& arg, Result const& result)
91     {
92 #ifdef BOOST_GEOMETRY_TEST_DEBUG
93         std::cout << "testing: " << typeid(Result).name()
94                   << " sqrt(" << typeid(Argument).name()
95                   << ")" << std::endl;
96 #endif
97         check<Argument, IsFundamental>::apply(arg, result);
98     }
99 };
100 
101 
102 
103 
104 
105 
106 // test cases
BOOST_AUTO_TEST_CASE(test_math_sqrt_fundamental)107 BOOST_AUTO_TEST_CASE( test_math_sqrt_fundamental )
108 {
109     static const double sqrt2 = std::sqrt(2.0);
110     static const long double sqrt2L = std::sqrt(2.0L);
111     static const float sqrt2F = std::sqrt(2.0F);
112 
113     check_sqrt<float, float>::apply(2.0F, sqrt2F);
114     check_sqrt<double, double>::apply(2.0, sqrt2);
115     check_sqrt<long double, long double>::apply(2.0L, sqrt2L);
116 
117     check_sqrt<char, double>::apply(2, sqrt2);
118     check_sqrt<signed char, double>::apply(2, sqrt2);
119     check_sqrt<short, double>::apply(2, sqrt2);
120     check_sqrt<int, double>::apply(2, sqrt2);
121     check_sqrt<long, double>::apply(2L, sqrt2);
122 #if !defined(BOOST_NO_LONG_LONG)
123     check_sqrt<long long, double>::apply(2LL, sqrt2);
124 #endif
125 #ifdef BOOST_HAS_LONG_LONG
126     check_sqrt
127         <
128             boost::long_long_type, double
129         >::apply(boost::long_long_type(2), sqrt2);
130 #endif
131 }
132 
133 
BOOST_AUTO_TEST_CASE(test_math_sqrt_custom)134 BOOST_AUTO_TEST_CASE( test_math_sqrt_custom )
135 {
136     typedef number_types::custom<double> custom1;
137     typedef custom_global<double> custom2;
138     typedef number_types::custom_with_global_sqrt<double> custom3;
139 
140     static const double sqrt2 = std::sqrt(2.0);
141 
142     check_sqrt<custom1, custom1>::apply(custom1(2.0), custom1(sqrt2));
143     check_sqrt<custom2, custom2>::apply(custom2(2.0), custom2(sqrt2));
144     check_sqrt<custom3, custom3>::apply(custom3(2.0), custom3(sqrt2));
145 
146 #ifdef HAVE_TTMATH
147     typedef ttmath_big custom4;
148     typedef ttmath::Big<1, 4> custom5;
149 
150     check_sqrt<custom4, custom4>::apply(custom4(2.0), custom4(sqrt2));
151     check_sqrt<custom5, custom5>::apply(custom5(2.0), custom5(sqrt2));
152 #endif
153 }
154