1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | // Unit Test |
3 | |
4 | // Copyright (c) 2014-2021, Oracle and/or its affiliates. |
5 | // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle |
6 | // Contributed and/or modified by Adam Wulkiewicz, 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 | #include <type_traits> |
18 | |
19 | #include <boost/test/included/unit_test.hpp> |
20 | |
21 | #include <boost/config.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/algorithms/not_implemented.hpp> |
30 | #include <boost/geometry/util/math.hpp> |
31 | |
32 | namespace bg = boost::geometry; |
33 | |
34 | |
35 | |
36 | |
37 | // call BOOST_CHECK |
38 | template |
39 | < |
40 | typename Argument, typename Result, |
41 | std::enable_if_t<std::is_fundamental<Argument>::value, int> = 0 |
42 | > |
43 | inline void check(Argument const& arg, Result const& result) |
44 | { |
45 | BOOST_CHECK_CLOSE(static_cast<double>(bg::math::sqrt(arg)), |
46 | static_cast<double>(result), |
47 | 0.00001); |
48 | } |
49 | |
50 | template |
51 | < |
52 | typename Argument, typename Result, |
53 | std::enable_if_t<! std::is_fundamental<Argument>::value, int> = 0 |
54 | > |
55 | inline void check(Argument const& arg, Result const& result) |
56 | { |
57 | Result const tol(0.00001); |
58 | BOOST_CHECK( bg::math::abs(bg::math::sqrt(arg) - result) < tol ); |
59 | } |
60 | |
61 | |
62 | // test sqrt return type and value |
63 | template <typename Argument, typename Result> |
64 | inline void check_sqrt(Argument const& arg, Result const& result) |
65 | { |
66 | using return_type = typename bg::math::detail::square_root<Argument>::return_type; |
67 | BOOST_GEOMETRY_STATIC_ASSERT((std::is_same<return_type, Result>::value), |
68 | "Wrong return type" , |
69 | return_type, Result); |
70 | |
71 | #ifdef BOOST_GEOMETRY_TEST_DEBUG |
72 | std::cout << "testing: " << typeid(Result).name() |
73 | << " sqrt(" << typeid(Argument).name() |
74 | << ")" << std::endl; |
75 | #endif |
76 | check<Argument, Result>(arg, result); |
77 | } |
78 | |
79 | |
80 | // test cases |
81 | BOOST_AUTO_TEST_CASE( test_math_sqrt_fundamental ) |
82 | { |
83 | static const double sqrt2 = std::sqrt(x: 2.0); |
84 | static const long double sqrt2L = std::sqrt(x: 2.0L); |
85 | static const float sqrt2F = std::sqrt(x: 2.0F); |
86 | |
87 | check_sqrt<float, float>(arg: 2.0F, result: sqrt2F); |
88 | check_sqrt<double, double>(arg: 2.0, result: sqrt2); |
89 | check_sqrt<long double, long double>(arg: 2.0L, result: sqrt2L); |
90 | |
91 | check_sqrt<char, double>(arg: 2, result: sqrt2); |
92 | check_sqrt<signed char, double>(arg: 2, result: sqrt2); |
93 | check_sqrt<short, double>(arg: 2, result: sqrt2); |
94 | check_sqrt<int, double>(arg: 2, result: sqrt2); |
95 | check_sqrt<long, double>(arg: 2L, result: sqrt2); |
96 | |
97 | check_sqrt<long long, double>(arg: 2LL, result: sqrt2); |
98 | } |
99 | |
100 | |
101 | BOOST_AUTO_TEST_CASE( test_math_sqrt_custom ) |
102 | { |
103 | typedef number_types::custom<double> custom1; |
104 | typedef custom_global<double> custom2; |
105 | typedef number_types::custom_with_global_sqrt<double> custom3; |
106 | |
107 | static const double sqrt2 = std::sqrt(x: 2.0); |
108 | |
109 | check_sqrt<custom1, custom1>(arg: custom1(2.0), result: custom1(sqrt2)); |
110 | check_sqrt<custom2, custom2>(arg: custom2(2.0), result: custom2(sqrt2)); |
111 | check_sqrt<custom3, custom3>(arg: custom3(2.0), result: custom3(sqrt2)); |
112 | } |
113 | |