Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:34:30

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 // Contains specializations for Boost.Rational
0018 
0019 #include <boost/rational.hpp>
0020 
0021 #include <boost/geometry/util/bounds.hpp>
0022 #include <boost/geometry/util/coordinate_cast.hpp>
0023 #include <boost/geometry/util/numeric_cast.hpp>
0024 #include <boost/geometry/util/select_most_precise.hpp>
0025 
0026 
0027 namespace boost{ namespace geometry
0028 {
0029 
0030 
0031 // Specialize for Boost.Geometry's coordinate cast
0032 // (from string to coordinate type)
0033 namespace detail
0034 {
0035 
0036 template <typename T>
0037 struct coordinate_cast<rational<T> >
0038 {
0039     static inline void split_parts(std::string const& source, std::string::size_type p,
0040         T& before, T& after, bool& negate, std::string::size_type& len)
0041     {
0042         std::string before_part = source.substr(0, p);
0043         std::string const after_part = source.substr(p + 1);
0044 
0045         negate = false;
0046 
0047         if (before_part.size() > 0 && before_part[0] == '-')
0048         {
0049             negate = true;
0050             before_part.erase(0, 1);
0051         }
0052         before = atol(before_part.c_str());
0053         after = atol(after_part.c_str());
0054         len = after_part.length();
0055     }
0056 
0057 
0058     static inline rational<T> apply(std::string const& source)
0059     {
0060         T before, after;
0061         bool negate;
0062         std::string::size_type len;
0063 
0064         // Note: decimal comma is not (yet) supported, it does (and should) not
0065         // occur in a WKT, where points are comma separated.
0066         std::string::size_type p = source.find('.');
0067         if (p == std::string::npos)
0068         {
0069             p = source.find('/');
0070             if (p == std::string::npos)
0071             {
0072                 return rational<T>(atol(source.c_str()));
0073             }
0074             split_parts(source, p, before, after, negate, len);
0075 
0076             return negate
0077                 ? -rational<T>(before, after)
0078                 : rational<T>(before, after)
0079                 ;
0080 
0081         }
0082 
0083         split_parts(source, p, before, after, negate, len);
0084 
0085         T den = 1;
0086         for (std::string::size_type i = 0; i < len; i++)
0087         {
0088             den *= 10;
0089         }
0090 
0091         return negate
0092             ? -rational<T>(before) - rational<T>(after, den)
0093             : rational<T>(before) + rational<T>(after, den)
0094             ;
0095     }
0096 };
0097 
0098 } // namespace detail
0099 
0100 // Specialize for Boost.Geometry's select_most_precise
0101 template <typename T1, typename T2>
0102 struct select_most_precise<boost::rational<T1>, boost::rational<T2> >
0103 {
0104     typedef typename boost::rational
0105         <
0106             typename select_most_precise<T1, T2>::type
0107         > type;
0108 };
0109 
0110 template <typename T>
0111 struct select_most_precise<boost::rational<T>, double>
0112 {
0113     typedef typename boost::rational<T> type;
0114 };
0115 
0116 namespace util
0117 {
0118 
0119 #ifndef DOXYGEN_NO_DETAIL
0120 namespace detail
0121 {
0122 
0123 // Specialize numeric_caster, needed for geomery::util::numeric_cast, for Boost.Rational
0124 // Without it, code using Boost.Rational does not compile
0125 template <typename Target, typename T>
0126 struct numeric_caster<Target, rational<T>>
0127 {
0128    static inline Target apply(rational<T> const& source)
0129     {
0130         return boost::rational_cast<Target>(source);
0131     }
0132 };
0133 
0134 } // namespace detail
0135 #endif
0136 
0137 
0138 // Specializes geometry::util::bounds for Boost.Rational
0139 // Without it, bounds contains (0,1) by default for Boost.Rational
0140 template<class T>
0141 struct bounds<rational<T> >
0142 {
0143     static inline rational<T> lowest()
0144     {
0145         return rational<T>(bounds<T>::lowest(), 1);
0146     }
0147     static inline rational<T> highest()
0148     {
0149         return rational<T>(bounds<T>::highest(), 1);
0150     }
0151 };
0152 
0153 } // namespace util
0154 
0155 }} // namespace boost::geometry
0156 
0157 
0158 #endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP