1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2012 Bruno Lalande, Paris, France. 5 // Copyright (c) 2012 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2018. 8 // Modifications copyright (c) 2018, Oracle and/or its affiliates. 9 10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 11 12 // Use, modification and distribution is subject to the Boost Software License, 13 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 14 // http://www.boost.org/LICENSE_1_0.txt) 15 16 #ifndef BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP 17 #define BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP 18 19 #include <boost/config.hpp> 20 #include <boost/mpl/if.hpp> 21 #include <boost/static_assert.hpp> 22 #include <boost/type_traits/is_floating_point.hpp> 23 #include <boost/type_traits/is_fundamental.hpp> 24 #include <boost/type_traits/is_void.hpp> 25 26 #include <boost/geometry/util/select_coordinate_type.hpp> 27 #include <boost/geometry/util/select_most_precise.hpp> 28 29 30 namespace boost { namespace geometry 31 { 32 33 namespace util 34 { 35 36 namespace detail 37 { 38 39 struct default_integral 40 { 41 #ifdef BOOST_HAS_LONG_LONG 42 typedef boost::long_long_type type; 43 #else 44 typedef int type; 45 #endif 46 }; 47 48 /*! 49 \details Selects the most appropriate: 50 - if calculation type is specified (not void), that one is used 51 - else if type is non-fundamental (user defined e.g. ttmath), that one 52 - else if type is floating point, the specified default FP is used 53 - else it is integral and the specified default integral is used 54 */ 55 template 56 < 57 typename Type, 58 typename CalculationType, 59 typename DefaultFloatingPointCalculationType, 60 typename DefaultIntegralCalculationType 61 > 62 struct calculation_type 63 { 64 BOOST_STATIC_ASSERT(( 65 boost::is_fundamental 66 < 67 DefaultFloatingPointCalculationType 68 >::type::value 69 )); 70 BOOST_STATIC_ASSERT(( 71 boost::is_fundamental 72 < 73 DefaultIntegralCalculationType 74 >::type::value 75 )); 76 77 78 typedef typename boost::mpl::if_ 79 < 80 boost::is_void<CalculationType>, 81 typename boost::mpl::if_ 82 < 83 boost::is_floating_point<Type>, 84 typename select_most_precise 85 < 86 DefaultFloatingPointCalculationType, 87 Type 88 >::type, 89 typename select_most_precise 90 < 91 DefaultIntegralCalculationType, 92 Type 93 >::type 94 >::type, 95 CalculationType 96 >::type type; 97 }; 98 99 } // namespace detail 100 101 102 namespace calculation_type 103 { 104 105 namespace geometric 106 { 107 108 template 109 < 110 typename Geometry, 111 typename CalculationType, 112 typename DefaultFloatingPointCalculationType = double, 113 typename DefaultIntegralCalculationType = detail::default_integral::type 114 > 115 struct unary 116 { 117 typedef typename detail::calculation_type 118 < 119 typename geometry::coordinate_type<Geometry>::type, 120 CalculationType, 121 DefaultFloatingPointCalculationType, 122 DefaultIntegralCalculationType 123 >::type type; 124 }; 125 126 template 127 < 128 typename Geometry1, 129 typename Geometry2, 130 typename CalculationType, 131 typename DefaultFloatingPointCalculationType = double, 132 typename DefaultIntegralCalculationType = detail::default_integral::type 133 > 134 struct binary 135 { 136 typedef typename detail::calculation_type 137 < 138 typename select_coordinate_type<Geometry1, Geometry2>::type, 139 CalculationType, 140 DefaultFloatingPointCalculationType, 141 DefaultIntegralCalculationType 142 >::type type; 143 }; 144 145 146 /*! 147 \brief calculation type (ternary, for three geometry types) 148 */ 149 template 150 < 151 typename Geometry1, 152 typename Geometry2, 153 typename Geometry3, 154 typename CalculationType, 155 typename DefaultFloatingPointCalculationType = double, 156 typename DefaultIntegralCalculationType = detail::default_integral::type 157 > 158 struct ternary 159 { 160 typedef typename detail::calculation_type 161 < 162 typename select_most_precise 163 < 164 typename coordinate_type<Geometry1>::type, 165 typename select_coordinate_type 166 < 167 Geometry2, 168 Geometry3 169 >::type 170 >::type, 171 CalculationType, 172 DefaultFloatingPointCalculationType, 173 DefaultIntegralCalculationType 174 >::type type; 175 }; 176 177 }} // namespace calculation_type::geometric 178 179 } // namespace util 180 181 }} // namespace boost::geometry 182 183 184 #endif // BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP 185