Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: // Copyright (c) 2011-2012 Bruno Lalande, Paris, France. Chris@16: // Copyright (c) 2011-2012 Mateusz Loskot, London, UK. Chris@16: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP Chris@16: #define BOOST_GEOMETRY_UTIL_RATIONAL_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@101: namespace boost{ namespace geometry Chris@101: { Chris@16: Chris@16: Chris@101: // Specialize for Boost.Geometry's coordinate cast Chris@16: // (from string to coordinate type) Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: template Chris@16: struct coordinate_cast > Chris@16: { Chris@16: static inline void split_parts(std::string const& source, std::string::size_type p, Chris@16: T& before, T& after, bool& negate, std::string::size_type& len) Chris@16: { Chris@16: std::string before_part = source.substr(0, p); Chris@16: std::string const after_part = source.substr(p + 1); Chris@16: Chris@16: negate = false; Chris@16: Chris@16: if (before_part.size() > 0 && before_part[0] == '-') Chris@16: { Chris@16: negate = true; Chris@16: before_part.erase(0, 1); Chris@16: } Chris@16: before = atol(before_part.c_str()); Chris@16: after = atol(after_part.c_str()); Chris@16: len = after_part.length(); Chris@16: } Chris@16: Chris@16: Chris@16: static inline rational apply(std::string const& source) Chris@16: { Chris@16: T before, after; Chris@16: bool negate; Chris@16: std::string::size_type len; Chris@16: Chris@16: // Note: decimal comma is not (yet) supported, it does (and should) not Chris@16: // occur in a WKT, where points are comma separated. Chris@16: std::string::size_type p = source.find("."); Chris@16: if (p == std::string::npos) Chris@16: { Chris@16: p = source.find("/"); Chris@16: if (p == std::string::npos) Chris@16: { Chris@16: return rational(atol(source.c_str())); Chris@16: } Chris@16: split_parts(source, p, before, after, negate, len); Chris@16: Chris@101: return negate Chris@16: ? -rational(before, after) Chris@16: : rational(before, after) Chris@16: ; Chris@16: Chris@16: } Chris@16: Chris@16: split_parts(source, p, before, after, negate, len); Chris@16: Chris@16: T den = 1; Chris@16: for (std::string::size_type i = 0; i < len; i++) Chris@16: { Chris@16: den *= 10; Chris@16: } Chris@16: Chris@101: return negate Chris@16: ? -rational(before) - rational(after, den) Chris@16: : rational(before) + rational(after, den) Chris@16: ; Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: // Specialize for Boost.Geometry's select_most_precise Chris@16: template Chris@16: struct select_most_precise, boost::rational > Chris@16: { Chris@16: typedef typename boost::rational Chris@16: < Chris@16: typename select_most_precise::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct select_most_precise, double> Chris@16: { Chris@16: typedef typename boost::rational type; Chris@16: }; Chris@16: Chris@16: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: Chris@16: // Specializes boost::rational to boost::numeric::bounds Chris@101: namespace boost { namespace numeric Chris@16: { Chris@16: Chris@16: template Chris@16: struct bounds > Chris@16: { Chris@101: static inline rational lowest() Chris@101: { Chris@101: return rational(bounds::lowest(), 1); Chris@16: } Chris@101: static inline rational highest() Chris@101: { Chris@101: return rational(bounds::highest(), 1); Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespace boost::numeric Chris@16: Chris@16: Chris@16: // Support for boost::numeric_cast to int and to double (necessary for SVG-mapper) Chris@16: namespace boost { namespace numeric Chris@16: { Chris@16: Chris@16: template Chris@16: < Chris@16: typename T, Chris@16: typename Traits, Chris@16: typename OverflowHandler, Chris@16: typename Float2IntRounder, Chris@16: typename RawConverter, Chris@16: typename UserRangeChecker Chris@16: > Chris@16: struct converter, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker> Chris@16: { Chris@16: static inline int convert(rational const& arg) Chris@16: { Chris@16: return int(rational_cast(arg)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: < Chris@16: typename T, Chris@16: typename Traits, Chris@16: typename OverflowHandler, Chris@16: typename Float2IntRounder, Chris@16: typename RawConverter, Chris@16: typename UserRangeChecker Chris@16: > Chris@16: struct converter, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker> Chris@16: { Chris@16: static inline double convert(rational const& arg) Chris@16: { Chris@16: return rational_cast(arg); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: }} Chris@16: Chris@16: Chris@16: #endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP