Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@16
|
4 // Copyright (c) 2011-2012 Bruno Lalande, Paris, France.
|
Chris@16
|
5 // Copyright (c) 2011-2012 Mateusz Loskot, London, UK.
|
Chris@16
|
6
|
Chris@16
|
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
Chris@16
|
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
Chris@16
|
9
|
Chris@16
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_UTIL_RATIONAL_HPP
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/rational.hpp>
|
Chris@16
|
18 #include <boost/numeric/conversion/bounds.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/geometry/util/coordinate_cast.hpp>
|
Chris@16
|
21 #include <boost/geometry/util/select_most_precise.hpp>
|
Chris@16
|
22
|
Chris@16
|
23
|
Chris@101
|
24 namespace boost{ namespace geometry
|
Chris@101
|
25 {
|
Chris@16
|
26
|
Chris@16
|
27
|
Chris@101
|
28 // Specialize for Boost.Geometry's coordinate cast
|
Chris@16
|
29 // (from string to coordinate type)
|
Chris@16
|
30 namespace detail
|
Chris@16
|
31 {
|
Chris@16
|
32
|
Chris@16
|
33 template <typename T>
|
Chris@16
|
34 struct coordinate_cast<rational<T> >
|
Chris@16
|
35 {
|
Chris@16
|
36 static inline void split_parts(std::string const& source, std::string::size_type p,
|
Chris@16
|
37 T& before, T& after, bool& negate, std::string::size_type& len)
|
Chris@16
|
38 {
|
Chris@16
|
39 std::string before_part = source.substr(0, p);
|
Chris@16
|
40 std::string const after_part = source.substr(p + 1);
|
Chris@16
|
41
|
Chris@16
|
42 negate = false;
|
Chris@16
|
43
|
Chris@16
|
44 if (before_part.size() > 0 && before_part[0] == '-')
|
Chris@16
|
45 {
|
Chris@16
|
46 negate = true;
|
Chris@16
|
47 before_part.erase(0, 1);
|
Chris@16
|
48 }
|
Chris@16
|
49 before = atol(before_part.c_str());
|
Chris@16
|
50 after = atol(after_part.c_str());
|
Chris@16
|
51 len = after_part.length();
|
Chris@16
|
52 }
|
Chris@16
|
53
|
Chris@16
|
54
|
Chris@16
|
55 static inline rational<T> apply(std::string const& source)
|
Chris@16
|
56 {
|
Chris@16
|
57 T before, after;
|
Chris@16
|
58 bool negate;
|
Chris@16
|
59 std::string::size_type len;
|
Chris@16
|
60
|
Chris@16
|
61 // Note: decimal comma is not (yet) supported, it does (and should) not
|
Chris@16
|
62 // occur in a WKT, where points are comma separated.
|
Chris@16
|
63 std::string::size_type p = source.find(".");
|
Chris@16
|
64 if (p == std::string::npos)
|
Chris@16
|
65 {
|
Chris@16
|
66 p = source.find("/");
|
Chris@16
|
67 if (p == std::string::npos)
|
Chris@16
|
68 {
|
Chris@16
|
69 return rational<T>(atol(source.c_str()));
|
Chris@16
|
70 }
|
Chris@16
|
71 split_parts(source, p, before, after, negate, len);
|
Chris@16
|
72
|
Chris@101
|
73 return negate
|
Chris@16
|
74 ? -rational<T>(before, after)
|
Chris@16
|
75 : rational<T>(before, after)
|
Chris@16
|
76 ;
|
Chris@16
|
77
|
Chris@16
|
78 }
|
Chris@16
|
79
|
Chris@16
|
80 split_parts(source, p, before, after, negate, len);
|
Chris@16
|
81
|
Chris@16
|
82 T den = 1;
|
Chris@16
|
83 for (std::string::size_type i = 0; i < len; i++)
|
Chris@16
|
84 {
|
Chris@16
|
85 den *= 10;
|
Chris@16
|
86 }
|
Chris@16
|
87
|
Chris@101
|
88 return negate
|
Chris@16
|
89 ? -rational<T>(before) - rational<T>(after, den)
|
Chris@16
|
90 : rational<T>(before) + rational<T>(after, den)
|
Chris@16
|
91 ;
|
Chris@16
|
92 }
|
Chris@16
|
93 };
|
Chris@16
|
94
|
Chris@16
|
95 } // namespace detail
|
Chris@16
|
96
|
Chris@16
|
97 // Specialize for Boost.Geometry's select_most_precise
|
Chris@16
|
98 template <typename T1, typename T2>
|
Chris@16
|
99 struct select_most_precise<boost::rational<T1>, boost::rational<T2> >
|
Chris@16
|
100 {
|
Chris@16
|
101 typedef typename boost::rational
|
Chris@16
|
102 <
|
Chris@16
|
103 typename select_most_precise<T1, T2>::type
|
Chris@16
|
104 > type;
|
Chris@16
|
105 };
|
Chris@16
|
106
|
Chris@16
|
107 template <typename T>
|
Chris@16
|
108 struct select_most_precise<boost::rational<T>, double>
|
Chris@16
|
109 {
|
Chris@16
|
110 typedef typename boost::rational<T> type;
|
Chris@16
|
111 };
|
Chris@16
|
112
|
Chris@16
|
113
|
Chris@16
|
114 }} // namespace boost::geometry
|
Chris@16
|
115
|
Chris@16
|
116
|
Chris@16
|
117 // Specializes boost::rational to boost::numeric::bounds
|
Chris@101
|
118 namespace boost { namespace numeric
|
Chris@16
|
119 {
|
Chris@16
|
120
|
Chris@16
|
121 template<class T>
|
Chris@16
|
122 struct bounds<rational<T> >
|
Chris@16
|
123 {
|
Chris@101
|
124 static inline rational<T> lowest()
|
Chris@101
|
125 {
|
Chris@101
|
126 return rational<T>(bounds<T>::lowest(), 1);
|
Chris@16
|
127 }
|
Chris@101
|
128 static inline rational<T> highest()
|
Chris@101
|
129 {
|
Chris@101
|
130 return rational<T>(bounds<T>::highest(), 1);
|
Chris@16
|
131 }
|
Chris@16
|
132 };
|
Chris@16
|
133
|
Chris@16
|
134 }} // namespace boost::numeric
|
Chris@16
|
135
|
Chris@16
|
136
|
Chris@16
|
137 // Support for boost::numeric_cast to int and to double (necessary for SVG-mapper)
|
Chris@16
|
138 namespace boost { namespace numeric
|
Chris@16
|
139 {
|
Chris@16
|
140
|
Chris@16
|
141 template
|
Chris@16
|
142 <
|
Chris@16
|
143 typename T,
|
Chris@16
|
144 typename Traits,
|
Chris@16
|
145 typename OverflowHandler,
|
Chris@16
|
146 typename Float2IntRounder,
|
Chris@16
|
147 typename RawConverter,
|
Chris@16
|
148 typename UserRangeChecker
|
Chris@16
|
149 >
|
Chris@16
|
150 struct converter<int, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
|
Chris@16
|
151 {
|
Chris@16
|
152 static inline int convert(rational<T> const& arg)
|
Chris@16
|
153 {
|
Chris@16
|
154 return int(rational_cast<double>(arg));
|
Chris@16
|
155 }
|
Chris@16
|
156 };
|
Chris@16
|
157
|
Chris@16
|
158 template
|
Chris@16
|
159 <
|
Chris@16
|
160 typename T,
|
Chris@16
|
161 typename Traits,
|
Chris@16
|
162 typename OverflowHandler,
|
Chris@16
|
163 typename Float2IntRounder,
|
Chris@16
|
164 typename RawConverter,
|
Chris@16
|
165 typename UserRangeChecker
|
Chris@16
|
166 >
|
Chris@16
|
167 struct converter<double, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
|
Chris@16
|
168 {
|
Chris@16
|
169 static inline double convert(rational<T> const& arg)
|
Chris@16
|
170 {
|
Chris@16
|
171 return rational_cast<double>(arg);
|
Chris@16
|
172 }
|
Chris@16
|
173 };
|
Chris@16
|
174
|
Chris@16
|
175
|
Chris@16
|
176 }}
|
Chris@16
|
177
|
Chris@16
|
178
|
Chris@16
|
179 #endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP
|