• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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