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