diff DEPENDENCIES/generic/include/boost/geometry/util/rational.hpp @ 16:2665513ce2d3

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