File indexing completed on 2025-07-05 08:34:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP
0015 #define BOOST_GEOMETRY_UTIL_RATIONAL_HPP
0016
0017
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
0032
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
0065
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 }
0099
0100
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
0124
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 }
0135 #endif
0136
0137
0138
0139
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 }
0154
0155 }}
0156
0157
0158 #endif