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