Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:42:18

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2011-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2011-2012 Mateusz Loskot, London, UK.
0006 
0007 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0008 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0009 
0010 // Use, modification and distribution is subject to the Boost Software License,
0011 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP
0015 #define BOOST_GEOMETRY_UTIL_RATIONAL_HPP
0016 
0017 #include <boost/rational.hpp>
0018 #include <boost/numeric/conversion/bounds.hpp>
0019 
0020 #include <boost/geometry/util/coordinate_cast.hpp>
0021 #include <boost/geometry/util/select_most_precise.hpp>
0022 
0023 
0024 namespace boost{ namespace geometry
0025 {
0026 
0027 
0028 // Specialize for Boost.Geometry's coordinate cast
0029 // (from string to coordinate type)
0030 namespace detail
0031 {
0032 
0033 template <typename T>
0034 struct coordinate_cast<rational<T> >
0035 {
0036     static inline void split_parts(std::string const& source, std::string::size_type p,
0037         T& before, T& after, bool& negate, std::string::size_type& len)
0038     {
0039         std::string before_part = source.substr(0, p);
0040         std::string const after_part = source.substr(p + 1);
0041 
0042         negate = false;
0043 
0044         if (before_part.size() > 0 && before_part[0] == '-')
0045         {
0046             negate = true;
0047             before_part.erase(0, 1);
0048         }
0049         before = atol(before_part.c_str());
0050         after = atol(after_part.c_str());
0051         len = after_part.length();
0052     }
0053 
0054 
0055     static inline rational<T> apply(std::string const& source)
0056     {
0057         T before, after;
0058         bool negate;
0059         std::string::size_type len;
0060 
0061         // Note: decimal comma is not (yet) supported, it does (and should) not
0062         // occur in a WKT, where points are comma separated.
0063         std::string::size_type p = source.find('.');
0064         if (p == std::string::npos)
0065         {
0066             p = source.find('/');
0067             if (p == std::string::npos)
0068             {
0069                 return rational<T>(atol(source.c_str()));
0070             }
0071             split_parts(source, p, before, after, negate, len);
0072 
0073             return negate
0074                 ? -rational<T>(before, after)
0075                 : rational<T>(before, after)
0076                 ;
0077 
0078         }
0079 
0080         split_parts(source, p, before, after, negate, len);
0081 
0082         T den = 1;
0083         for (std::string::size_type i = 0; i < len; i++)
0084         {
0085             den *= 10;
0086         }
0087 
0088         return negate
0089             ? -rational<T>(before) - rational<T>(after, den)
0090             : rational<T>(before) + rational<T>(after, den)
0091             ;
0092     }
0093 };
0094 
0095 } // namespace detail
0096 
0097 // Specialize for Boost.Geometry's select_most_precise
0098 template <typename T1, typename T2>
0099 struct select_most_precise<boost::rational<T1>, boost::rational<T2> >
0100 {
0101     typedef typename boost::rational
0102         <
0103             typename select_most_precise<T1, T2>::type
0104         > type;
0105 };
0106 
0107 template <typename T>
0108 struct select_most_precise<boost::rational<T>, double>
0109 {
0110     typedef typename boost::rational<T> type;
0111 };
0112 
0113 
0114 }} // namespace boost::geometry
0115 
0116 
0117 // Specializes boost::rational to boost::numeric::bounds
0118 namespace boost { namespace numeric
0119 {
0120 
0121 template<class T>
0122 struct bounds<rational<T> >
0123 {
0124     static inline rational<T> lowest()
0125     {
0126         return rational<T>(bounds<T>::lowest(), 1);
0127     }
0128     static inline rational<T> highest()
0129     {
0130         return rational<T>(bounds<T>::highest(), 1);
0131     }
0132 };
0133 
0134 }} // namespace boost::numeric
0135 
0136 
0137 // Support for boost::numeric_cast to int and to double (necessary for SVG-mapper)
0138 namespace boost { namespace numeric
0139 {
0140 
0141 template
0142 <
0143     typename T,
0144     typename Traits,
0145     typename OverflowHandler,
0146     typename Float2IntRounder,
0147     typename RawConverter,
0148     typename UserRangeChecker
0149 >
0150 struct converter<int, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
0151 {
0152     static inline int convert(rational<T> const& arg)
0153     {
0154         return int(rational_cast<double>(arg));
0155     }
0156 };
0157 
0158 template
0159 <
0160     typename T,
0161     typename Traits,
0162     typename OverflowHandler,
0163     typename Float2IntRounder,
0164     typename RawConverter,
0165     typename UserRangeChecker
0166 >
0167 struct converter<double, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
0168 {
0169     static inline double convert(rational<T> const& arg)
0170     {
0171         return rational_cast<double>(arg);
0172     }
0173 };
0174 
0175 
0176 }}
0177 
0178 
0179 #endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP