1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
14 #ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP
15 #define BOOST_GEOMETRY_UTIL_RATIONAL_HPP
17 #include <boost/rational.hpp>
18 #include <boost/numeric/conversion/bounds.hpp>
20 #include <boost/geometry/util/coordinate_cast.hpp>
21 #include <boost/geometry/util/select_most_precise.hpp>
24 namespace boost{ namespace geometry
28 // Specialize for Boost.Geometry's coordinate cast
29 // (from string to coordinate type)
34 struct coordinate_cast<rational<T> >
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)
39 std::string before_part = source.substr(0, p);
40 std::string const after_part = source.substr(p + 1);
44 if (before_part.size() > 0 && before_part[0] == '-')
47 before_part.erase(0, 1);
49 before = atol(before_part.c_str());
50 after = atol(after_part.c_str());
51 len = after_part.length();
55 static inline rational<T> apply(std::string const& source)
59 std::string::size_type len;
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)
67 if (p == std::string::npos)
69 return rational<T>(atol(source.c_str()));
71 split_parts(source, p, before, after, negate, len);
74 ? -rational<T>(before, after)
75 : rational<T>(before, after)
80 split_parts(source, p, before, after, negate, len);
83 for (std::string::size_type i = 0; i < len; i++)
89 ? -rational<T>(before) - rational<T>(after, den)
90 : rational<T>(before) + rational<T>(after, den)
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> >
101 typedef typename boost::rational
103 typename select_most_precise<T1, T2>::type
107 template <typename T>
108 struct select_most_precise<boost::rational<T>, double>
110 typedef typename boost::rational<T> type;
114 }} // namespace boost::geometry
117 // Specializes boost::rational to boost::numeric::bounds
118 namespace boost { namespace numeric
122 struct bounds<rational<T> >
124 static inline rational<T> lowest()
126 return rational<T>(bounds<T>::lowest(), 1);
128 static inline rational<T> highest()
130 return rational<T>(bounds<T>::highest(), 1);
134 }} // namespace boost::numeric
137 // Support for boost::numeric_cast to int and to double (necessary for SVG-mapper)
138 namespace boost { namespace numeric
145 typename OverflowHandler,
146 typename Float2IntRounder,
147 typename RawConverter,
148 typename UserRangeChecker
150 struct converter<int, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
152 static inline int convert(rational<T> const& arg)
154 return int(rational_cast<double>(arg));
162 typename OverflowHandler,
163 typename Float2IntRounder,
164 typename RawConverter,
165 typename UserRangeChecker
167 struct converter<double, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
169 static inline double convert(rational<T> const& arg)
171 return rational_cast<double>(arg);
179 #endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP