stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_ADD_CONST_IF_C_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function to define a const or non const type
|
||||
\ingroup utility
|
||||
\details If the boolean template parameter is true, the type parameter
|
||||
will be defined as const, otherwise it will be defined as it was.
|
||||
This meta-function is used to have one implementation for both
|
||||
const and non const references
|
||||
\note This traits class is completely independant from Boost.Geometry
|
||||
and might be a separate addition to Boost
|
||||
\note Used in a.o. for_each, interior_rings, exterior_ring
|
||||
\par Example
|
||||
\code
|
||||
void foo(typename add_const_if_c<IsConst, Point>::type& point)
|
||||
\endcode
|
||||
*/
|
||||
template <bool IsConst, typename Type>
|
||||
struct add_const_if_c
|
||||
{
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
IsConst,
|
||||
Type const,
|
||||
Type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP
|
||||
@@ -0,0 +1,52 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_BARE_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_BARE_TYPE_HPP
|
||||
|
||||
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct bare_type
|
||||
{
|
||||
typedef typename boost::remove_const
|
||||
<
|
||||
typename boost::remove_pointer
|
||||
<
|
||||
typename boost::remove_reference
|
||||
<
|
||||
T
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace util
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_BARE_TYPE_HPP
|
||||
@@ -0,0 +1,178 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// 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_CALCULATION_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct default_integral
|
||||
{
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef boost::long_long_type type;
|
||||
#else
|
||||
typedef int type;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
\details Selects the most appropriate:
|
||||
- if calculation type is specified (not void), that one is used
|
||||
- else if type is non-fundamental (user defined e.g. ttmath), that one
|
||||
- else if type is floating point, the specified default FP is used
|
||||
- else it is integral and the specified default integral is used
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Type,
|
||||
typename CalculationType,
|
||||
typename DefaultFloatingPointCalculationType,
|
||||
typename DefaultIntegralCalculationType
|
||||
>
|
||||
struct calculation_type
|
||||
{
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_fundamental
|
||||
<
|
||||
DefaultFloatingPointCalculationType
|
||||
>::type::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_fundamental
|
||||
<
|
||||
DefaultIntegralCalculationType
|
||||
>::type::value
|
||||
));
|
||||
|
||||
|
||||
typedef typename boost::mpl::if_
|
||||
<
|
||||
boost::is_void<CalculationType>,
|
||||
typename boost::mpl::if_
|
||||
<
|
||||
boost::is_floating_point<Type>,
|
||||
typename select_most_precise
|
||||
<
|
||||
DefaultFloatingPointCalculationType,
|
||||
Type
|
||||
>::type,
|
||||
typename select_most_precise
|
||||
<
|
||||
DefaultIntegralCalculationType,
|
||||
Type
|
||||
>::type
|
||||
>::type,
|
||||
CalculationType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
namespace calculation_type
|
||||
{
|
||||
|
||||
namespace geometric
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename CalculationType,
|
||||
typename DefaultFloatingPointCalculationType = double,
|
||||
typename DefaultIntegralCalculationType = detail::default_integral::type
|
||||
>
|
||||
struct unary
|
||||
{
|
||||
typedef typename detail::calculation_type
|
||||
<
|
||||
typename geometry::coordinate_type<Geometry>::type,
|
||||
CalculationType,
|
||||
DefaultFloatingPointCalculationType,
|
||||
DefaultIntegralCalculationType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename CalculationType,
|
||||
typename DefaultFloatingPointCalculationType = double,
|
||||
typename DefaultIntegralCalculationType = detail::default_integral::type
|
||||
>
|
||||
struct binary
|
||||
{
|
||||
typedef typename detail::calculation_type
|
||||
<
|
||||
typename select_coordinate_type<Geometry1, Geometry2>::type,
|
||||
CalculationType,
|
||||
DefaultFloatingPointCalculationType,
|
||||
DefaultIntegralCalculationType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief calculation type (ternary, for three geometry types)
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Geometry3,
|
||||
typename CalculationType,
|
||||
typename DefaultFloatingPointCalculationType = double,
|
||||
typename DefaultIntegralCalculationType = detail::default_integral::type
|
||||
>
|
||||
struct ternary
|
||||
{
|
||||
typedef typename detail::calculation_type
|
||||
<
|
||||
typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<Geometry1>::type,
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry2,
|
||||
Geometry3
|
||||
>::type
|
||||
>::type,
|
||||
CalculationType,
|
||||
DefaultFloatingPointCalculationType,
|
||||
DefaultIntegralCalculationType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
}} // namespace calculation_type::geometric
|
||||
|
||||
} // namespace util
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
|
||||
@@ -0,0 +1,46 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_CLOSURE_AS_BOOL_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_CLOSURE_AS_BOOL_HPP
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
template<closure_selector Closure>
|
||||
struct closure_as_bool
|
||||
{};
|
||||
|
||||
|
||||
template<>
|
||||
struct closure_as_bool<closed>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct closure_as_bool<open>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_CLOSURE_AS_BOOL_HPP
|
||||
@@ -0,0 +1,92 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// 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_COMBINE_IF_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
|
||||
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bind.hpp>
|
||||
#include <boost/mpl/set.hpp>
|
||||
#include <boost/mpl/insert.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function to generate all the combination of pairs of types
|
||||
from a given sequence Sequence except those that does not satisfy the
|
||||
predicate Pred
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef boost::mpl::vector<boost::mpl::int_<0>, boost::mpl::int_<1> > types;
|
||||
typedef combine_if<types, types, always<true_> >::type combinations;
|
||||
typedef boost::mpl::vector<
|
||||
pair<boost::mpl::int_<1>, boost::mpl::int_<1> >,
|
||||
pair<boost::mpl::int_<1>, boost::mpl::int_<0> >,
|
||||
pair<boost::mpl::int_<0>, boost::mpl::int_<1> >,
|
||||
pair<boost::mpl::int_<0>, boost::mpl::int_<0> >
|
||||
> result_types;
|
||||
|
||||
BOOST_MPL_ASSERT(( boost::mpl::equal<combinations, result_types> ));
|
||||
\endcode
|
||||
*/
|
||||
template <typename Sequence1, typename Sequence2, typename Pred>
|
||||
struct combine_if
|
||||
{
|
||||
struct combine
|
||||
{
|
||||
template <typename Result, typename T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename boost::mpl::fold<Sequence2, Result,
|
||||
boost::mpl::if_
|
||||
<
|
||||
boost::mpl::bind
|
||||
<
|
||||
typename boost::mpl::lambda<Pred>::type,
|
||||
T,
|
||||
boost::mpl::_2
|
||||
>,
|
||||
boost::mpl::insert
|
||||
<
|
||||
boost::mpl::_1, boost::mpl::pair<T, boost::mpl::_2>
|
||||
>,
|
||||
boost::mpl::_1
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
typedef typename boost::mpl::fold
|
||||
<
|
||||
Sequence1, boost::mpl::set0<>, combine
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace util
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
|
||||
@@ -0,0 +1,106 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// 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_COMPRESS_VARIANT_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/insert.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/set.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Variant>
|
||||
struct unique_types:
|
||||
boost::mpl::fold<
|
||||
typename boost::mpl::reverse_fold<
|
||||
typename Variant::types,
|
||||
boost::mpl::set<>,
|
||||
boost::mpl::insert<
|
||||
boost::mpl::placeholders::_1,
|
||||
boost::mpl::placeholders::_2
|
||||
>
|
||||
>::type,
|
||||
boost::mpl::vector<>,
|
||||
boost::mpl::push_back
|
||||
<
|
||||
boost::mpl::placeholders::_1, boost::mpl::placeholders::_2
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Types>
|
||||
struct variant_or_single:
|
||||
boost::mpl::if_<
|
||||
boost::mpl::equal_to<
|
||||
boost::mpl::size<Types>,
|
||||
boost::mpl::int_<1>
|
||||
>,
|
||||
typename boost::mpl::front<Types>::type,
|
||||
typename make_variant_over<Types>::type
|
||||
>
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a boost::variant type and tries to minimize
|
||||
it by doing the following:
|
||||
- if there's any duplicate types, remove them
|
||||
- if the result is a variant of one type, turn it into just that type
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef variant<int, float, int, long> variant_type;
|
||||
typedef compress_variant<variant_type>::type compressed;
|
||||
typedef boost::mpl::vector<int, float, long> result_types;
|
||||
BOOST_MPL_ASSERT(( boost::mpl::equal<compressed::types, result_types> ));
|
||||
|
||||
typedef variant<int, int, int> one_type_variant_type;
|
||||
typedef compress_variant<one_type_variant_type>::type single_type;
|
||||
BOOST_MPL_ASSERT(( boost::equals<single_type, int> ));
|
||||
\endcode
|
||||
*/
|
||||
|
||||
template <typename Variant>
|
||||
struct compress_variant:
|
||||
detail::variant_or_single<
|
||||
typename detail::unique_types<Variant>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP
|
||||
@@ -0,0 +1,44 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_CONDITION_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_CONDITION_HPP
|
||||
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
|
||||
// The macro defined in this file allows to suppress the MSVC
|
||||
// compiler warning C4127: conditional expression is constant
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
||||
// NOTE: The code commented out below contains an alternative implementation
|
||||
// of a macro using a free function. It was left here in case if in the future
|
||||
// version of MSVC for the code currently used in the macro implementation
|
||||
// the warning was generated.
|
||||
|
||||
//#ifndef DOXYGEN_NO_DETAIL
|
||||
//namespace boost { namespace geometry { namespace detail {
|
||||
//BOOST_FORCEINLINE bool condition(bool const b) { return b; }
|
||||
//}}} // boost::geometry::detail
|
||||
//#endif // DOXYGEN_NO_DETAIL
|
||||
//#define BOOST_GEOMETRY_CONDITION(CONDITION) boost::geometry::detail::condition(CONDITION)
|
||||
|
||||
#define BOOST_GEOMETRY_CONDITION(CONDITION) ((void)0, (CONDITION))
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_GEOMETRY_CONDITION(CONDITION) (CONDITION)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_CONDITION_HPP
|
||||
@@ -0,0 +1,55 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_COORDINATE_CAST_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_COORDINATE_CAST_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief cast coordinates from a string to a coordinate type
|
||||
\detail By default it uses lexical_cast. However, lexical_cast seems not to support
|
||||
ttmath / partial specializations. Therefore this small utility is added.
|
||||
See also "define_pi" where the same issue is solved
|
||||
*/
|
||||
template <typename CoordinateType>
|
||||
struct coordinate_cast
|
||||
{
|
||||
static inline CoordinateType apply(std::string const& source)
|
||||
{
|
||||
#if defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
|
||||
return atof(source.c_str());
|
||||
#else
|
||||
return boost::lexical_cast<CoordinateType>(source);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_COORDINATE_CAST_HPP
|
||||
@@ -0,0 +1,94 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_FOR_EACH_COORDINATE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_FOR_EACH_COORDINATE_HPP
|
||||
|
||||
#include <boost/concept/requires.hpp>
|
||||
#include <boost/geometry/geometries/concepts/point_concept.hpp>
|
||||
#include <boost/geometry/util/add_const_if_c.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Point, int Dimension, int DimensionCount, bool IsConst>
|
||||
struct coordinates_scanner
|
||||
{
|
||||
template <typename Op>
|
||||
static inline Op apply(typename add_const_if_c
|
||||
<
|
||||
IsConst,
|
||||
Point
|
||||
>::type& point, Op operation)
|
||||
{
|
||||
operation.template apply<Point, Dimension>(point);
|
||||
return coordinates_scanner
|
||||
<
|
||||
Point,
|
||||
Dimension+1,
|
||||
DimensionCount,
|
||||
IsConst
|
||||
>::apply(point, operation);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, int DimensionCount, bool IsConst>
|
||||
struct coordinates_scanner<Point, DimensionCount, DimensionCount, IsConst>
|
||||
{
|
||||
template <typename Op>
|
||||
static inline Op apply(typename add_const_if_c
|
||||
<
|
||||
IsConst,
|
||||
Point
|
||||
>::type& , Op operation)
|
||||
{
|
||||
return operation;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
template <typename Point, typename Op>
|
||||
inline void for_each_coordinate(Point& point, Op operation)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
|
||||
|
||||
typedef typename detail::coordinates_scanner
|
||||
<
|
||||
Point, 0, dimension<Point>::type::value, false
|
||||
> scanner;
|
||||
|
||||
scanner::apply(point, operation);
|
||||
}
|
||||
|
||||
template <typename Point, typename Op>
|
||||
inline Op for_each_coordinate(Point const& point, Op operation)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point>) );
|
||||
|
||||
typedef typename detail::coordinates_scanner
|
||||
<
|
||||
Point, 0, dimension<Point>::type::value, true
|
||||
> scanner;
|
||||
|
||||
return scanner::apply(point, operation);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_FOR_EACH_COORDINATE_HPP
|
||||
@@ -0,0 +1,55 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// 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_HAS_INFINITE_COORDINATE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_HAS_INFINITE_COORDINATE_HPP
|
||||
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/util/has_nan_coordinate.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct isinf
|
||||
{
|
||||
template <typename T>
|
||||
static inline bool apply(T const& t)
|
||||
{
|
||||
return boost::math::isinf(t);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
template <typename Point>
|
||||
bool has_infinite_coordinate(Point const& point)
|
||||
{
|
||||
return detail::has_coordinate_with_property
|
||||
<
|
||||
Point,
|
||||
detail::isinf,
|
||||
boost::is_floating_point
|
||||
<
|
||||
typename coordinate_type<Point>::type
|
||||
>::value
|
||||
>::apply(point);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_HAS_INFINITE_COORDINATE_HPP
|
||||
@@ -0,0 +1,99 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// 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_HAS_NAN_COORDINATE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_HAS_NAN_COORDINATE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct isnan
|
||||
{
|
||||
template <typename T>
|
||||
static inline bool apply(T const& t)
|
||||
{
|
||||
return boost::math::isnan(t);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Predicate,
|
||||
bool Enable,
|
||||
std::size_t I = 0,
|
||||
std::size_t N = geometry::dimension<Point>::value
|
||||
>
|
||||
struct has_coordinate_with_property
|
||||
{
|
||||
static bool apply(Point const& point)
|
||||
{
|
||||
return Predicate::apply(geometry::get<I>(point))
|
||||
|| has_coordinate_with_property
|
||||
<
|
||||
Point, Predicate, Enable, I+1, N
|
||||
>::apply(point);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Predicate, std::size_t I, std::size_t N>
|
||||
struct has_coordinate_with_property<Point, Predicate, false, I, N>
|
||||
{
|
||||
static inline bool apply(Point const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Predicate, std::size_t N>
|
||||
struct has_coordinate_with_property<Point, Predicate, true, N, N>
|
||||
{
|
||||
static bool apply(Point const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
template <typename Point>
|
||||
bool has_nan_coordinate(Point const& point)
|
||||
{
|
||||
return detail::has_coordinate_with_property
|
||||
<
|
||||
Point,
|
||||
detail::isnan,
|
||||
boost::is_floating_point
|
||||
<
|
||||
typename coordinate_type<Point>::type
|
||||
>::value
|
||||
>::apply(point);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_HAS_NAN_COORDINATE_HPP
|
||||
@@ -0,0 +1,55 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// 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_HAS_NON_FINITE_COORDINATE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_HAS_NON_FINITE_COORDINATE_HPP
|
||||
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/util/has_nan_coordinate.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct is_not_finite
|
||||
{
|
||||
template <typename T>
|
||||
static inline bool apply(T const& t)
|
||||
{
|
||||
return ! boost::math::isfinite(t);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
template <typename Point>
|
||||
bool has_non_finite_coordinate(Point const& point)
|
||||
{
|
||||
return detail::has_coordinate_with_property
|
||||
<
|
||||
Point,
|
||||
detail::is_not_finite,
|
||||
boost::is_floating_point
|
||||
<
|
||||
typename coordinate_type<Point>::type
|
||||
>::value
|
||||
>::apply(point);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_HAS_NON_FINITE_COORDINATE_HPP
|
||||
@@ -0,0 +1,779 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015.
|
||||
// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_MATH_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_MATH_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
//#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace math
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
inline T const& greatest(T const& v1, T const& v2)
|
||||
{
|
||||
return (std::max)(v1, v2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T const& greatest(T const& v1, T const& v2, T const& v3)
|
||||
{
|
||||
return (std::max)(greatest(v1, v2), v3);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4)
|
||||
{
|
||||
return (std::max)(greatest(v1, v2, v3), v4);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4, T const& v5)
|
||||
{
|
||||
return (std::max)(greatest(v1, v2, v3, v4), v5);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T bounded(T const& v, T const& lower, T const& upper)
|
||||
{
|
||||
return (std::min)((std::max)(v, lower), upper);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T bounded(T const& v, T const& lower)
|
||||
{
|
||||
return (std::max)(v, lower);
|
||||
}
|
||||
|
||||
|
||||
template <typename T,
|
||||
bool IsFloatingPoint = boost::is_floating_point<T>::value>
|
||||
struct abs
|
||||
{
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
T const zero = T();
|
||||
return value < zero ? -value : value;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct abs<T, true>
|
||||
{
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
using ::fabs;
|
||||
using std::fabs; // for long double
|
||||
|
||||
return fabs(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct equals_default_policy
|
||||
{
|
||||
template <typename T>
|
||||
static inline T apply(T const& a, T const& b)
|
||||
{
|
||||
// See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
|
||||
return greatest(abs<T>::apply(a), abs<T>::apply(b), T(1));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T,
|
||||
bool IsFloatingPoint = boost::is_floating_point<T>::value>
|
||||
struct equals_factor_policy
|
||||
{
|
||||
equals_factor_policy()
|
||||
: factor(1) {}
|
||||
explicit equals_factor_policy(T const& v)
|
||||
: factor(greatest(abs<T>::apply(v), T(1)))
|
||||
{}
|
||||
equals_factor_policy(T const& v0, T const& v1, T const& v2, T const& v3)
|
||||
: factor(greatest(abs<T>::apply(v0), abs<T>::apply(v1),
|
||||
abs<T>::apply(v2), abs<T>::apply(v3),
|
||||
T(1)))
|
||||
{}
|
||||
|
||||
T const& apply(T const&, T const&) const
|
||||
{
|
||||
return factor;
|
||||
}
|
||||
|
||||
T factor;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct equals_factor_policy<T, false>
|
||||
{
|
||||
equals_factor_policy() {}
|
||||
explicit equals_factor_policy(T const&) {}
|
||||
equals_factor_policy(T const& , T const& , T const& , T const& ) {}
|
||||
|
||||
static inline T apply(T const&, T const&)
|
||||
{
|
||||
return T(1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type,
|
||||
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
|
||||
struct equals
|
||||
{
|
||||
template <typename Policy>
|
||||
static inline bool apply(Type const& a, Type const& b, Policy const&)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct equals<Type, true>
|
||||
{
|
||||
template <typename Policy>
|
||||
static inline bool apply(Type const& a, Type const& b, Policy const& policy)
|
||||
{
|
||||
boost::ignore_unused(policy);
|
||||
|
||||
if (a == b)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (boost::math::isfinite(a) && boost::math::isfinite(b))
|
||||
{
|
||||
// If a is INF and b is e.g. 0, the expression below returns true
|
||||
// but the values are obviously not equal, hence the condition
|
||||
return abs<Type>::apply(a - b)
|
||||
<= std::numeric_limits<Type>::epsilon() * policy.apply(a, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename Policy>
|
||||
inline bool equals_by_policy(T1 const& a, T2 const& b, Policy const& policy)
|
||||
{
|
||||
return detail::equals
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(a, b, policy);
|
||||
}
|
||||
|
||||
template <typename Type,
|
||||
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
|
||||
struct smaller
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct smaller<Type, true>
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
if (!(a < b)) // a >= b
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! equals<Type, true>::apply(b, a, equals_default_policy());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type,
|
||||
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
|
||||
struct smaller_or_equals
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct smaller_or_equals<Type, true>
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
if (a <= b)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return equals<Type, true>::apply(a, b, equals_default_policy());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Type,
|
||||
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
|
||||
struct equals_with_epsilon
|
||||
: public equals<Type, IsFloatingPoint>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
bool IsFundemantal = boost::is_fundamental<T>::value /* false */
|
||||
>
|
||||
struct square_root
|
||||
{
|
||||
typedef T return_type;
|
||||
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
// for non-fundamental number types assume that sqrt is
|
||||
// defined either:
|
||||
// 1) at T's scope, or
|
||||
// 2) at global scope, or
|
||||
// 3) in namespace std
|
||||
using ::sqrt;
|
||||
using std::sqrt;
|
||||
|
||||
return sqrt(value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FundamentalFP>
|
||||
struct square_root_for_fundamental_fp
|
||||
{
|
||||
typedef FundamentalFP return_type;
|
||||
|
||||
static inline FundamentalFP apply(FundamentalFP const& value)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
|
||||
// This is a workaround for some 32-bit platforms.
|
||||
// For some of those platforms it has been reported that
|
||||
// std::sqrt(nan) and/or std::sqrt(-nan) returns a finite value.
|
||||
// For those platforms we need to define the macro
|
||||
// BOOST_GEOMETRY_SQRT_CHECK_FINITENESS so that the argument
|
||||
// to std::sqrt is checked appropriately before passed to std::sqrt
|
||||
if (boost::math::isfinite(value))
|
||||
{
|
||||
return std::sqrt(value);
|
||||
}
|
||||
else if (boost::math::isinf(value) && value < 0)
|
||||
{
|
||||
return -std::numeric_limits<FundamentalFP>::quiet_NaN();
|
||||
}
|
||||
return value;
|
||||
#else
|
||||
// for fundamental floating point numbers use std::sqrt
|
||||
return std::sqrt(value);
|
||||
#endif // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct square_root<float, true>
|
||||
: square_root_for_fundamental_fp<float>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct square_root<double, true>
|
||||
: square_root_for_fundamental_fp<double>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct square_root<long double, true>
|
||||
: square_root_for_fundamental_fp<long double>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct square_root<T, true>
|
||||
{
|
||||
typedef double return_type;
|
||||
|
||||
static inline double apply(T const& value)
|
||||
{
|
||||
// for all other fundamental number types use also std::sqrt
|
||||
//
|
||||
// Note: in C++98 the only other possibility is double;
|
||||
// in C++11 there are also overloads for integral types;
|
||||
// this specialization works for those as well.
|
||||
return square_root_for_fundamental_fp
|
||||
<
|
||||
double
|
||||
>::apply(boost::numeric_cast<double>(value));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
bool IsFundemantal = boost::is_fundamental<T>::value /* false */
|
||||
>
|
||||
struct modulo
|
||||
{
|
||||
typedef T return_type;
|
||||
|
||||
static inline T apply(T const& value1, T const& value2)
|
||||
{
|
||||
// for non-fundamental number types assume that a free
|
||||
// function mod() is defined either:
|
||||
// 1) at T's scope, or
|
||||
// 2) at global scope
|
||||
return mod(value1, value2);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Fundamental,
|
||||
bool IsIntegral = boost::is_integral<Fundamental>::value
|
||||
>
|
||||
struct modulo_for_fundamental
|
||||
{
|
||||
typedef Fundamental return_type;
|
||||
|
||||
static inline Fundamental apply(Fundamental const& value1,
|
||||
Fundamental const& value2)
|
||||
{
|
||||
return value1 % value2;
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for floating-point numbers
|
||||
template <typename Fundamental>
|
||||
struct modulo_for_fundamental<Fundamental, false>
|
||||
{
|
||||
typedef Fundamental return_type;
|
||||
|
||||
static inline Fundamental apply(Fundamental const& value1,
|
||||
Fundamental const& value2)
|
||||
{
|
||||
return std::fmod(value1, value2);
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for fundamental number type
|
||||
template <typename Fundamental>
|
||||
struct modulo<Fundamental, true>
|
||||
: modulo_for_fundamental<Fundamental>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short constructs to enable partial specialization for PI, 2*PI
|
||||
and PI/2, currently not possible in Math.
|
||||
*/
|
||||
template <typename T>
|
||||
struct define_pi
|
||||
{
|
||||
static inline T apply()
|
||||
{
|
||||
// Default calls Boost.Math
|
||||
return boost::math::constants::pi<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct define_two_pi
|
||||
{
|
||||
static inline T apply()
|
||||
{
|
||||
// Default calls Boost.Math
|
||||
return boost::math::constants::two_pi<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct define_half_pi
|
||||
{
|
||||
static inline T apply()
|
||||
{
|
||||
// Default calls Boost.Math
|
||||
return boost::math::constants::half_pi<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct relaxed_epsilon
|
||||
{
|
||||
static inline T apply(const T& factor)
|
||||
{
|
||||
return factor * std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
};
|
||||
|
||||
// This must be consistent with math::equals.
|
||||
// By default math::equals() scales the error by epsilon using the greater of
|
||||
// compared values but here is only one value, though it should work the same way.
|
||||
// (a-a) <= max(a, a) * EPS -> 0 <= a*EPS
|
||||
// (a+da-a) <= max(a+da, a) * EPS -> da <= (a+da)*EPS
|
||||
template <typename T, bool IsFloat = boost::is_floating_point<T>::value>
|
||||
struct scaled_epsilon
|
||||
{
|
||||
static inline T apply(T const& val)
|
||||
{
|
||||
return (std::max)(abs<T>::apply(val), T(1))
|
||||
* std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct scaled_epsilon<T, false>
|
||||
{
|
||||
static inline T apply(T const&)
|
||||
{
|
||||
return T(0);
|
||||
}
|
||||
};
|
||||
|
||||
// ItoF ItoI FtoF
|
||||
template <typename Result, typename Source,
|
||||
bool ResultIsInteger = std::numeric_limits<Result>::is_integer,
|
||||
bool SourceIsInteger = std::numeric_limits<Source>::is_integer>
|
||||
struct rounding_cast
|
||||
{
|
||||
static inline Result apply(Source const& v)
|
||||
{
|
||||
return boost::numeric_cast<Result>(v);
|
||||
}
|
||||
};
|
||||
|
||||
// TtoT
|
||||
template <typename Source, bool ResultIsInteger, bool SourceIsInteger>
|
||||
struct rounding_cast<Source, Source, ResultIsInteger, SourceIsInteger>
|
||||
{
|
||||
static inline Source apply(Source const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
// FtoI
|
||||
template <typename Result, typename Source>
|
||||
struct rounding_cast<Result, Source, true, false>
|
||||
{
|
||||
static inline Result apply(Source const& v)
|
||||
{
|
||||
return boost::numeric_cast<Result>(v < Source(0) ?
|
||||
v - Source(0.5) :
|
||||
v + Source(0.5));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T pi() { return detail::define_pi<T>::apply(); }
|
||||
|
||||
template <typename T>
|
||||
inline T two_pi() { return detail::define_two_pi<T>::apply(); }
|
||||
|
||||
template <typename T>
|
||||
inline T half_pi() { return detail::define_half_pi<T>::apply(); }
|
||||
|
||||
template <typename T>
|
||||
inline T relaxed_epsilon(T const& factor)
|
||||
{
|
||||
return detail::relaxed_epsilon<T>::apply(factor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T scaled_epsilon(T const& value)
|
||||
{
|
||||
return detail::scaled_epsilon<T>::apply(value);
|
||||
}
|
||||
|
||||
|
||||
// Maybe replace this by boost equals or so
|
||||
|
||||
/*!
|
||||
\brief returns true if both arguments are equal.
|
||||
\ingroup utility
|
||||
\param a first argument
|
||||
\param b second argument
|
||||
\return true if a == b
|
||||
\note If both a and b are of an integral type, comparison is done by ==.
|
||||
If one of the types is floating point, comparison is done by abs and
|
||||
comparing with epsilon. If one of the types is non-fundamental, it might
|
||||
be a high-precision number and comparison is done using the == operator
|
||||
of that class.
|
||||
*/
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool equals(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::equals
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(a, b, detail::equals_default_policy());
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool equals_with_epsilon(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::equals_with_epsilon
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(a, b, detail::equals_default_policy());
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool smaller(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::smaller
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(a, b);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool larger(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::smaller
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(b, a);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool smaller_or_equals(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::smaller_or_equals
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(a, b);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool larger_or_equals(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::smaller_or_equals
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(b, a);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T d2r()
|
||||
{
|
||||
static T const conversion_coefficient = geometry::math::pi<T>() / T(180.0);
|
||||
return conversion_coefficient;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T r2d()
|
||||
{
|
||||
static T const conversion_coefficient = T(180.0) / geometry::math::pi<T>();
|
||||
return conversion_coefficient;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail {
|
||||
|
||||
template <typename DegreeOrRadian>
|
||||
struct as_radian
|
||||
{
|
||||
template <typename T>
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct as_radian<degree>
|
||||
{
|
||||
template <typename T>
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
return value * d2r<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DegreeOrRadian>
|
||||
struct from_radian
|
||||
{
|
||||
template <typename T>
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct from_radian<degree>
|
||||
{
|
||||
template <typename T>
|
||||
static inline T apply(T const& value)
|
||||
{
|
||||
return value * r2d<T>();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif
|
||||
|
||||
template <typename DegreeOrRadian, typename T>
|
||||
inline T as_radian(T const& value)
|
||||
{
|
||||
return detail::as_radian<DegreeOrRadian>::apply(value);
|
||||
}
|
||||
|
||||
template <typename DegreeOrRadian, typename T>
|
||||
inline T from_radian(T const& value)
|
||||
{
|
||||
return detail::from_radian<DegreeOrRadian>::apply(value);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Calculates the haversine of an angle
|
||||
\ingroup utility
|
||||
\note See http://en.wikipedia.org/wiki/Haversine_formula
|
||||
haversin(alpha) = sin2(alpha/2)
|
||||
*/
|
||||
template <typename T>
|
||||
inline T hav(T const& theta)
|
||||
{
|
||||
T const half = T(0.5);
|
||||
T const sn = sin(half * theta);
|
||||
return sn * sn;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to return the square
|
||||
\ingroup utility
|
||||
\param value Value to calculate the square from
|
||||
\return The squared value
|
||||
*/
|
||||
template <typename T>
|
||||
inline T sqr(T const& value)
|
||||
{
|
||||
return value * value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to return the square root
|
||||
\ingroup utility
|
||||
\param value Value to calculate the square root from
|
||||
\return The square root value
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename detail::square_root<T>::return_type
|
||||
sqrt(T const& value)
|
||||
{
|
||||
return detail::square_root
|
||||
<
|
||||
T, boost::is_fundamental<T>::value
|
||||
>::apply(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to return the modulo of two values
|
||||
\ingroup utility
|
||||
\param value1 First value
|
||||
\param value2 Second value
|
||||
\return The result of the modulo operation on the (ordered) pair
|
||||
(value1, value2)
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename detail::modulo<T>::return_type
|
||||
mod(T const& value1, T const& value2)
|
||||
{
|
||||
return detail::modulo
|
||||
<
|
||||
T, boost::is_fundamental<T>::value
|
||||
>::apply(value1, value2);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to workaround gcc/clang problem that abs is converting to integer
|
||||
and that older versions of MSVC does not support abs of long long...
|
||||
\ingroup utility
|
||||
*/
|
||||
template<typename T>
|
||||
inline T abs(T const& value)
|
||||
{
|
||||
return detail::abs<T>::apply(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to calculate the sign of a number: -1 (negative), 0 (zero), 1 (positive)
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename T>
|
||||
inline int sign(T const& value)
|
||||
{
|
||||
T const zero = T();
|
||||
return value > zero ? 1 : value < zero ? -1 : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to cast a value possibly rounding it to the nearest
|
||||
integral value.
|
||||
\ingroup utility
|
||||
\note If the source T is NOT an integral type and Result is an integral type
|
||||
the value is rounded towards the closest integral value. Otherwise it's
|
||||
casted without rounding.
|
||||
*/
|
||||
template <typename Result, typename T>
|
||||
inline Result rounding_cast(T const& v)
|
||||
{
|
||||
return detail::rounding_cast<Result, T>::apply(v);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_MATH_HPP
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace math
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
||||
template <typename Units, typename CoordinateType>
|
||||
class normalize_spheroidal_box_coordinates
|
||||
{
|
||||
private:
|
||||
typedef normalize_spheroidal_coordinates<Units, CoordinateType> normalize;
|
||||
typedef constants_on_spheroid<CoordinateType, Units> constants;
|
||||
|
||||
static inline bool is_band(CoordinateType const& longitude1,
|
||||
CoordinateType const& longitude2)
|
||||
{
|
||||
return ! math::smaller(math::abs(longitude1 - longitude2),
|
||||
constants::period());
|
||||
}
|
||||
|
||||
public:
|
||||
static inline void apply(CoordinateType& longitude1,
|
||||
CoordinateType& latitude1,
|
||||
CoordinateType& longitude2,
|
||||
CoordinateType& latitude2,
|
||||
bool band)
|
||||
{
|
||||
normalize::apply(longitude1, latitude1, false);
|
||||
normalize::apply(longitude2, latitude2, false);
|
||||
|
||||
if (math::equals(latitude1, constants::min_latitude())
|
||||
&& math::equals(latitude2, constants::min_latitude()))
|
||||
{
|
||||
// box degenerates to the south pole
|
||||
longitude1 = longitude2 = CoordinateType(0);
|
||||
}
|
||||
else if (math::equals(latitude1, constants::max_latitude())
|
||||
&& math::equals(latitude2, constants::max_latitude()))
|
||||
{
|
||||
// box degenerates to the north pole
|
||||
longitude1 = longitude2 = CoordinateType(0);
|
||||
}
|
||||
else if (band)
|
||||
{
|
||||
// the box is a band between two small circles (parallel
|
||||
// to the equator) on the spheroid
|
||||
longitude1 = constants::min_longitude();
|
||||
longitude2 = constants::max_longitude();
|
||||
}
|
||||
else if (longitude1 > longitude2)
|
||||
{
|
||||
// the box crosses the antimeridian, so we need to adjust
|
||||
// the longitudes
|
||||
longitude2 += constants::period();
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(latitude1, latitude2));
|
||||
BOOST_GEOMETRY_ASSERT(! math::smaller(latitude1, constants::min_latitude()));
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(latitude2, constants::max_latitude()));
|
||||
#endif
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2));
|
||||
BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude()));
|
||||
BOOST_GEOMETRY_ASSERT
|
||||
(! math::larger(longitude2 - longitude1, constants::period()));
|
||||
}
|
||||
|
||||
static inline void apply(CoordinateType& longitude1,
|
||||
CoordinateType& latitude1,
|
||||
CoordinateType& longitude2,
|
||||
CoordinateType& latitude2)
|
||||
{
|
||||
bool const band = is_band(longitude1, longitude2);
|
||||
|
||||
apply(longitude1, latitude1, longitude2, latitude2, band);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to normalize the coordinates of a box on a spheroid
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude1 Minimum longitude of the box
|
||||
\param latitude1 Minimum latitude of the box
|
||||
\param longitude2 Maximum longitude of the box
|
||||
\param latitude2 Maximum latitude of the box
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
|
||||
CoordinateType& latitude1,
|
||||
CoordinateType& longitude2,
|
||||
CoordinateType& latitude2)
|
||||
{
|
||||
detail::normalize_spheroidal_box_coordinates
|
||||
<
|
||||
Units, CoordinateType
|
||||
>::apply(longitude1, latitude1, longitude2, latitude2);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to normalize the coordinates of a box on a spheroid
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude1 Minimum longitude of the box
|
||||
\param latitude1 Minimum latitude of the box
|
||||
\param longitude2 Maximum longitude of the box
|
||||
\param latitude2 Maximum latitude of the box
|
||||
\param band Indicates whether the box should be treated as a band or
|
||||
not and avoid the computation done in the other version of the function
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
|
||||
CoordinateType& latitude1,
|
||||
CoordinateType& longitude2,
|
||||
CoordinateType& latitude2,
|
||||
bool band)
|
||||
{
|
||||
detail::normalize_spheroidal_box_coordinates
|
||||
<
|
||||
Units, CoordinateType
|
||||
>::apply(longitude1, latitude1, longitude2, latitude2, band);
|
||||
}
|
||||
|
||||
|
||||
} // namespace math
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
|
||||
+324
@@ -0,0 +1,324 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015-2016, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace math
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
||||
template <typename CoordinateType, typename Units>
|
||||
struct constants_on_spheroid
|
||||
{
|
||||
static inline CoordinateType period()
|
||||
{
|
||||
return math::two_pi<CoordinateType>();
|
||||
}
|
||||
|
||||
static inline CoordinateType half_period()
|
||||
{
|
||||
return math::pi<CoordinateType>();
|
||||
}
|
||||
|
||||
static inline CoordinateType min_longitude()
|
||||
{
|
||||
static CoordinateType const minus_pi = -math::pi<CoordinateType>();
|
||||
return minus_pi;
|
||||
}
|
||||
|
||||
static inline CoordinateType max_longitude()
|
||||
{
|
||||
return math::pi<CoordinateType>();
|
||||
}
|
||||
|
||||
static inline CoordinateType min_latitude()
|
||||
{
|
||||
static CoordinateType const minus_half_pi
|
||||
= -math::half_pi<CoordinateType>();
|
||||
return minus_half_pi;
|
||||
}
|
||||
|
||||
static inline CoordinateType max_latitude()
|
||||
{
|
||||
return math::half_pi<CoordinateType>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CoordinateType>
|
||||
struct constants_on_spheroid<CoordinateType, degree>
|
||||
{
|
||||
static inline CoordinateType period()
|
||||
{
|
||||
return CoordinateType(360.0);
|
||||
}
|
||||
|
||||
static inline CoordinateType half_period()
|
||||
{
|
||||
return CoordinateType(180.0);
|
||||
}
|
||||
|
||||
static inline CoordinateType min_longitude()
|
||||
{
|
||||
return CoordinateType(-180.0);
|
||||
}
|
||||
|
||||
static inline CoordinateType max_longitude()
|
||||
{
|
||||
return CoordinateType(180.0);
|
||||
}
|
||||
|
||||
static inline CoordinateType min_latitude()
|
||||
{
|
||||
return CoordinateType(-90.0);
|
||||
}
|
||||
|
||||
static inline CoordinateType max_latitude()
|
||||
{
|
||||
return CoordinateType(90.0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Units, typename CoordinateType>
|
||||
class normalize_spheroidal_coordinates
|
||||
{
|
||||
typedef constants_on_spheroid<CoordinateType, Units> constants;
|
||||
|
||||
protected:
|
||||
static inline CoordinateType normalize_up(CoordinateType const& value)
|
||||
{
|
||||
return
|
||||
math::mod(value + constants::half_period(), constants::period())
|
||||
- constants::half_period();
|
||||
}
|
||||
|
||||
static inline CoordinateType normalize_down(CoordinateType const& value)
|
||||
{
|
||||
return
|
||||
math::mod(value - constants::half_period(), constants::period())
|
||||
+ constants::half_period();
|
||||
}
|
||||
|
||||
public:
|
||||
static inline void apply(CoordinateType& longitude)
|
||||
{
|
||||
// normalize longitude
|
||||
if (math::equals(math::abs(longitude), constants::half_period()))
|
||||
{
|
||||
longitude = constants::half_period();
|
||||
}
|
||||
else if (longitude > constants::half_period())
|
||||
{
|
||||
longitude = normalize_up(longitude);
|
||||
if (math::equals(longitude, -constants::half_period()))
|
||||
{
|
||||
longitude = constants::half_period();
|
||||
}
|
||||
}
|
||||
else if (longitude < -constants::half_period())
|
||||
{
|
||||
longitude = normalize_down(longitude);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void apply(CoordinateType& longitude,
|
||||
CoordinateType& latitude,
|
||||
bool normalize_poles = true)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
|
||||
// normalize latitude
|
||||
if (math::larger(latitude, constants::half_period()))
|
||||
{
|
||||
latitude = normalize_up(latitude);
|
||||
}
|
||||
else if (math::smaller(latitude, -constants::half_period()))
|
||||
{
|
||||
latitude = normalize_down(latitude);
|
||||
}
|
||||
|
||||
// fix latitude range
|
||||
if (latitude < constants::min_latitude())
|
||||
{
|
||||
latitude = -constants::half_period() - latitude;
|
||||
longitude -= constants::half_period();
|
||||
}
|
||||
else if (latitude > constants::max_latitude())
|
||||
{
|
||||
latitude = constants::half_period() - latitude;
|
||||
longitude -= constants::half_period();
|
||||
}
|
||||
#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
|
||||
|
||||
// normalize longitude
|
||||
apply(longitude);
|
||||
|
||||
// finally normalize poles
|
||||
if (normalize_poles)
|
||||
{
|
||||
if (math::equals(math::abs(latitude), constants::max_latitude()))
|
||||
{
|
||||
// for the north and south pole we set the longitude to 0
|
||||
// (works for both radians and degrees)
|
||||
longitude = CoordinateType(0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(constants::min_latitude(), latitude));
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(latitude, constants::max_latitude()));
|
||||
#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(math::smaller(constants::min_longitude(), longitude));
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to normalize the coordinates on a spheroid
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude Longitude
|
||||
\param latitude Latitude
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline void normalize_spheroidal_coordinates(CoordinateType& longitude,
|
||||
CoordinateType& latitude)
|
||||
{
|
||||
detail::normalize_spheroidal_coordinates
|
||||
<
|
||||
Units, CoordinateType
|
||||
>::apply(longitude, latitude);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to normalize the longitude on a spheroid.
|
||||
Note that in general both coordinates should be normalized at once.
|
||||
This utility is suitable e.g. for normalization of the difference of longitudes.
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude Longitude
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline void normalize_longitude(CoordinateType& longitude)
|
||||
{
|
||||
detail::normalize_spheroidal_coordinates
|
||||
<
|
||||
Units, CoordinateType
|
||||
>::apply(longitude);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to calculate difference between two longitudes
|
||||
normalized in range (-180, 180].
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude1 Longitude 1
|
||||
\param longitude2 Longitude 2
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline CoordinateType longitude_distance_signed(CoordinateType const& longitude1,
|
||||
CoordinateType const& longitude2)
|
||||
{
|
||||
CoordinateType diff = longitude2 - longitude1;
|
||||
math::normalize_longitude<Units, CoordinateType>(diff);
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to calculate difference between two longitudes
|
||||
normalized in range [0, 360).
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude1 Longitude 1
|
||||
\param longitude2 Longitude 2
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline CoordinateType longitude_distance_unsigned(CoordinateType const& longitude1,
|
||||
CoordinateType const& longitude2)
|
||||
{
|
||||
typedef math::detail::constants_on_spheroid
|
||||
<
|
||||
CoordinateType, Units
|
||||
> constants;
|
||||
|
||||
CoordinateType const c0 = 0;
|
||||
CoordinateType diff = longitude_distance_signed<Units>(longitude1, longitude2);
|
||||
if (diff < c0) // (-180, 180] -> [0, 360)
|
||||
{
|
||||
diff += constants::period();
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief The abs difference between longitudes in range [0, 180].
|
||||
\tparam Units The units of the coordindate system in the spheroid
|
||||
\tparam CoordinateType The type of the coordinates
|
||||
\param longitude1 Longitude 1
|
||||
\param longitude2 Longitude 2
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline CoordinateType longitude_difference(CoordinateType const& longitude1,
|
||||
CoordinateType const& longitude2)
|
||||
{
|
||||
return math::abs(math::longitude_distance_signed<Units>(longitude1, longitude2));
|
||||
}
|
||||
|
||||
template <typename Units, typename CoordinateType>
|
||||
inline CoordinateType longitude_interval_distance_signed(CoordinateType const& longitude_a1,
|
||||
CoordinateType const& longitude_a2,
|
||||
CoordinateType const& longitude_b)
|
||||
{
|
||||
CoordinateType const c0 = 0;
|
||||
CoordinateType dist_a12 = longitude_distance_signed<Units>(longitude_a1, longitude_a2);
|
||||
CoordinateType dist_a1b = longitude_distance_signed<Units>(longitude_a1, longitude_b);
|
||||
if (dist_a12 < c0)
|
||||
{
|
||||
dist_a12 = -dist_a12;
|
||||
dist_a1b = -dist_a1b;
|
||||
}
|
||||
|
||||
return dist_a1b < c0 ? dist_a1b
|
||||
: dist_a1b > dist_a12 ? dist_a1b - dist_a12
|
||||
: c0;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
|
||||
@@ -0,0 +1,46 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_ORDER_AS_DIRECTION_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_ORDER_AS_DIRECTION_HPP
|
||||
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
template<order_selector Order>
|
||||
struct order_as_direction
|
||||
{};
|
||||
|
||||
|
||||
template<>
|
||||
struct order_as_direction<clockwise>
|
||||
{
|
||||
static const iterate_direction value = iterate_forward;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct order_as_direction<counterclockwise>
|
||||
{
|
||||
static const iterate_direction value = iterate_reverse;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_ORDER_AS_DIRECTION_HPP
|
||||
@@ -0,0 +1,75 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_PARAMETER_TYPE_OF_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
|
||||
|
||||
|
||||
#include <boost/function_types/function_arity.hpp>
|
||||
#include <boost/function_types/is_member_function_pointer.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/plus.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function selecting a parameter type of a (member) function, by index
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Method, std::size_t Index>
|
||||
struct parameter_type_of
|
||||
{
|
||||
typedef typename boost::function_types::parameter_types
|
||||
<
|
||||
Method
|
||||
>::type parameter_types;
|
||||
|
||||
typedef typename boost::mpl::if_
|
||||
<
|
||||
boost::function_types::is_member_function_pointer<Method>,
|
||||
boost::mpl::int_<1>,
|
||||
boost::mpl::int_<0>
|
||||
>::type base_index_type;
|
||||
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
Index == 0,
|
||||
base_index_type,
|
||||
typename boost::mpl::plus
|
||||
<
|
||||
base_index_type,
|
||||
boost::mpl::int_<Index>
|
||||
>::type
|
||||
>::type indexed_type;
|
||||
|
||||
typedef typename boost::remove_reference
|
||||
<
|
||||
typename boost::mpl::at
|
||||
<
|
||||
parameter_types,
|
||||
indexed_type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
|
||||
@@ -0,0 +1,50 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-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_PROMOTE_FLOATING_POINT_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function converting, if necessary, to "a floating point" type
|
||||
\details
|
||||
- if input type is integer, type is double
|
||||
- else type is input type
|
||||
\ingroup utility
|
||||
*/
|
||||
|
||||
template <typename T, typename PromoteIntegerTo = double>
|
||||
struct promote_floating_point
|
||||
{
|
||||
typedef typename
|
||||
boost::mpl::if_
|
||||
<
|
||||
boost::is_integral<T>,
|
||||
PromoteIntegerTo,
|
||||
T
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
|
||||
@@ -0,0 +1,318 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
|
||||
|
||||
// For now deactivate the use of multiprecision integers
|
||||
// TODO: activate it later
|
||||
#define BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <boost/mpl/end.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
|
||||
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_unsigned.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace promote_integral
|
||||
{
|
||||
|
||||
// meta-function that returns the bit size of a type
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
bool IsFundamental = boost::is_fundamental<T>::type::value
|
||||
>
|
||||
struct bit_size
|
||||
{};
|
||||
|
||||
|
||||
// for fundamental types, just return CHAR_BIT * sizeof(T)
|
||||
template <typename T>
|
||||
struct bit_size<T, true>
|
||||
: boost::mpl::size_t<(CHAR_BIT * sizeof(T))>
|
||||
{};
|
||||
|
||||
|
||||
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
|
||||
// partial specialization for cpp_int
|
||||
template
|
||||
<
|
||||
unsigned MinSize,
|
||||
unsigned MaxSize,
|
||||
boost::multiprecision::cpp_integer_type SignType,
|
||||
boost::multiprecision::cpp_int_check_type Checked,
|
||||
typename Allocator,
|
||||
boost::multiprecision::expression_template_option ExpressionTemplates
|
||||
>
|
||||
struct bit_size
|
||||
<
|
||||
boost::multiprecision::number
|
||||
<
|
||||
boost::multiprecision::cpp_int_backend
|
||||
<
|
||||
MinSize, MaxSize, SignType, Checked, Allocator
|
||||
>,
|
||||
ExpressionTemplates
|
||||
>,
|
||||
false
|
||||
> : boost::mpl::size_t<MaxSize>
|
||||
{};
|
||||
#endif // BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
typename Iterator,
|
||||
typename EndIterator,
|
||||
std::size_t MinSize
|
||||
>
|
||||
struct promote_to_larger
|
||||
{
|
||||
typedef typename boost::mpl::deref<Iterator>::type current_type;
|
||||
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
(bit_size<current_type>::type::value >= MinSize),
|
||||
current_type,
|
||||
typename promote_to_larger
|
||||
<
|
||||
T,
|
||||
typename boost::mpl::next<Iterator>::type,
|
||||
EndIterator,
|
||||
MinSize
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// The following specialization is required to finish the loop over
|
||||
// all list elements
|
||||
template <typename T, typename EndIterator, std::size_t MinSize>
|
||||
struct promote_to_larger<T, EndIterator, EndIterator, MinSize>
|
||||
{
|
||||
// if promotion fails, keep the number T
|
||||
// (and cross fingers that overflow will not occur)
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
}} // namespace detail::promote_integral
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function to define an integral type with size
|
||||
than is (roughly) twice the bit size of T
|
||||
\ingroup utility
|
||||
\details
|
||||
This meta-function tries to promote the fundamental integral type T
|
||||
to a another integral type with size (roughly) twice the bit size of T.
|
||||
|
||||
To do this, two times the bit size of T is tested against the bit sizes of:
|
||||
short, int, long, boost::long_long_type, boost::int128_t
|
||||
and the one that first matches is chosen.
|
||||
|
||||
For unsigned types the bit size of T is tested against the bit
|
||||
sizes of the types above, if T is promoted to a signed type, or
|
||||
the bit sizes of
|
||||
unsigned short, unsigned int, unsigned long, std::size_t,
|
||||
boost::ulong_long_type, boost::uint128_t
|
||||
if T is promoted to an unsigned type.
|
||||
|
||||
By default an unsigned type is promoted to a signed type.
|
||||
This behavior is controlled by the PromoteUnsignedToUnsigned
|
||||
boolean template parameter, whose default value is "false".
|
||||
To promote an unsigned type to an unsigned type set the value of
|
||||
this template parameter to "true".
|
||||
|
||||
If the macro BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is not
|
||||
defined, boost's multiprecision integer cpp_int<> is used as a
|
||||
last resort.
|
||||
|
||||
If BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is defined and an
|
||||
appropriate type cannot be detected, the input type is returned as is.
|
||||
|
||||
Finally, if the passed type is either a floating-point type or a
|
||||
user-defined type it is returned as is.
|
||||
|
||||
\note boost::long_long_type and boost::ulong_long_type are
|
||||
considered only if the macro BOOST_HAS_LONG_LONG is defined
|
||||
|
||||
\note boost::int128_type and boost::uint128_type are considered
|
||||
only if the macros BOOST_HAS_INT128 and BOOST_GEOMETRY_ENABLE_INT128
|
||||
are defined
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
bool PromoteUnsignedToUnsigned = false,
|
||||
bool UseCheckedInteger = false,
|
||||
bool IsIntegral = boost::is_integral<T>::type::value
|
||||
>
|
||||
class promote_integral
|
||||
{
|
||||
private:
|
||||
static bool const is_unsigned = boost::is_unsigned<T>::type::value;
|
||||
|
||||
typedef detail::promote_integral::bit_size<T> bit_size_type;
|
||||
|
||||
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
|
||||
// Define the proper check policy for the multiprecision integer
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
UseCheckedInteger,
|
||||
boost::integral_constant
|
||||
<
|
||||
boost::multiprecision::cpp_int_check_type,
|
||||
boost::multiprecision::checked
|
||||
>,
|
||||
boost::integral_constant
|
||||
<
|
||||
boost::multiprecision::cpp_int_check_type,
|
||||
boost::multiprecision::unchecked
|
||||
>
|
||||
>::type check_policy_type;
|
||||
|
||||
// Meta-function to get the multiprecision integer type for the
|
||||
// given size and sign type (signed/unsigned)
|
||||
template
|
||||
<
|
||||
unsigned int Size,
|
||||
boost::multiprecision::cpp_integer_type SignType
|
||||
>
|
||||
struct multiprecision_integer_type
|
||||
{
|
||||
typedef boost::multiprecision::number
|
||||
<
|
||||
boost::multiprecision::cpp_int_backend
|
||||
<
|
||||
Size,
|
||||
Size,
|
||||
SignType,
|
||||
check_policy_type::value,
|
||||
void
|
||||
>
|
||||
> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
// Define the minimum size (in bits) needed for the promoted type
|
||||
// If T is the input type and P the promoted type, then the
|
||||
// minimum number of bits for P are (below b stands for the number
|
||||
// of bits of T):
|
||||
// * if T is unsigned and P is unsigned: 2 * b
|
||||
// * if T is signed and P is signed: 2 * b - 1
|
||||
// * if T is unsigned and P is signed: 2 * b + 1
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
(PromoteUnsignedToUnsigned && is_unsigned),
|
||||
boost::mpl::size_t<(2 * bit_size_type::value)>,
|
||||
typename boost::mpl::if_c
|
||||
<
|
||||
is_unsigned,
|
||||
boost::mpl::size_t<(2 * bit_size_type::value + 1)>,
|
||||
boost::mpl::size_t<(2 * bit_size_type::value - 1)>
|
||||
>::type
|
||||
>::type min_bit_size_type;
|
||||
|
||||
// Define the list of signed integral types we are going to use
|
||||
// for promotion
|
||||
typedef boost::mpl::list
|
||||
<
|
||||
short, int, long
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
, boost::long_long_type
|
||||
#endif
|
||||
#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
|
||||
, boost::int128_type
|
||||
#endif
|
||||
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
|
||||
, typename multiprecision_integer_type
|
||||
<
|
||||
min_bit_size_type::value,
|
||||
boost::multiprecision::signed_magnitude
|
||||
>::type
|
||||
#endif
|
||||
> signed_integral_types;
|
||||
|
||||
// Define the list of unsigned integral types we are going to use
|
||||
// for promotion
|
||||
typedef boost::mpl::list
|
||||
<
|
||||
unsigned short, unsigned int, unsigned long, std::size_t
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
, boost::ulong_long_type
|
||||
#endif
|
||||
#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
|
||||
, boost::uint128_type
|
||||
#endif
|
||||
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
|
||||
, typename multiprecision_integer_type
|
||||
<
|
||||
min_bit_size_type::value,
|
||||
boost::multiprecision::unsigned_magnitude
|
||||
>::type
|
||||
#endif
|
||||
> unsigned_integral_types;
|
||||
|
||||
// Define the list of integral types that will be used for
|
||||
// promotion (depending in whether we was to promote unsigned to
|
||||
// unsigned or not)
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
(is_unsigned && PromoteUnsignedToUnsigned),
|
||||
unsigned_integral_types,
|
||||
signed_integral_types
|
||||
>::type integral_types;
|
||||
|
||||
public:
|
||||
typedef typename detail::promote_integral::promote_to_larger
|
||||
<
|
||||
T,
|
||||
typename boost::mpl::begin<integral_types>::type,
|
||||
typename boost::mpl::end<integral_types>::type,
|
||||
min_bit_size_type::value
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
|
||||
class promote_integral
|
||||
<
|
||||
T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
|
||||
@@ -0,0 +1,418 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2016.
|
||||
// Modifications copyright (c) 2013-2016 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_RANGE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/empty.hpp>
|
||||
#include <boost/range/difference_type.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/rbegin.hpp>
|
||||
#include <boost/range/reference.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace range {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// NOTE: For SinglePassRanges pos could iterate over all elements until the i-th element was met.
|
||||
|
||||
template <typename RandomAccessRange>
|
||||
struct pos
|
||||
{
|
||||
typedef typename boost::range_iterator<RandomAccessRange>::type iterator;
|
||||
typedef typename boost::range_size<RandomAccessRange>::type size_type;
|
||||
typedef typename boost::range_difference<RandomAccessRange>::type difference_type;
|
||||
|
||||
static inline iterator apply(RandomAccessRange & rng, size_type i)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange> ));
|
||||
return boost::begin(rng) + static_cast<difference_type>(i);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return an iterator of a RandomAccessRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename RandomAccessRange>
|
||||
inline typename boost::range_iterator<RandomAccessRange const>::type
|
||||
pos(RandomAccessRange const& rng,
|
||||
typename boost::range_size<RandomAccessRange const>::type i)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
|
||||
return detail::pos<RandomAccessRange const>::apply(rng, i);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return an iterator of a RandomAccessRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename RandomAccessRange>
|
||||
inline typename boost::range_iterator<RandomAccessRange>::type
|
||||
pos(RandomAccessRange & rng,
|
||||
typename boost::range_size<RandomAccessRange>::type i)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
|
||||
return detail::pos<RandomAccessRange>::apply(rng, i);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return an element of a RandomAccessRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename RandomAccessRange>
|
||||
inline typename boost::range_reference<RandomAccessRange const>::type
|
||||
at(RandomAccessRange const& rng,
|
||||
typename boost::range_size<RandomAccessRange const>::type i)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
|
||||
return * detail::pos<RandomAccessRange const>::apply(rng, i);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return an element of a RandomAccessRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename RandomAccessRange>
|
||||
inline typename boost::range_reference<RandomAccessRange>::type
|
||||
at(RandomAccessRange & rng,
|
||||
typename boost::range_size<RandomAccessRange>::type i)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
|
||||
return * detail::pos<RandomAccessRange>::apply(rng, i);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the front element of a Range.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_reference<Range const>::type
|
||||
front(Range const& rng)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
|
||||
return *boost::begin(rng);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the front element of a Range.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_reference<Range>::type
|
||||
front(Range & rng)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
|
||||
return *boost::begin(rng);
|
||||
}
|
||||
|
||||
// NOTE: For SinglePassRanges back() could iterate over all elements until the last element is met.
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the back element of a BidirectionalRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename BidirectionalRange>
|
||||
inline typename boost::range_reference<BidirectionalRange const>::type
|
||||
back(BidirectionalRange const& rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
|
||||
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
|
||||
return *(boost::rbegin(rng));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the back element of a BidirectionalRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename BidirectionalRange>
|
||||
inline typename boost::range_reference<BidirectionalRange>::type
|
||||
back(BidirectionalRange & rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept<BidirectionalRange>));
|
||||
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
|
||||
return *(boost::rbegin(rng));
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently clear a mutable range.
|
||||
It uses traits::clear<>.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline void clear(Range & rng)
|
||||
{
|
||||
// NOTE: this trait is probably not needed since it could be implemented using resize()
|
||||
geometry::traits::clear<Range>::apply(rng);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently insert a new element at the end of a mutable range.
|
||||
It uses boost::geometry::traits::push_back<>.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline void push_back(Range & rng,
|
||||
typename boost::range_value<Range>::type const& value)
|
||||
{
|
||||
geometry::traits::push_back<Range>::apply(rng, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently resize a mutable range.
|
||||
It uses boost::geometry::traits::resize<>.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline void resize(Range & rng,
|
||||
typename boost::range_size<Range>::type new_size)
|
||||
{
|
||||
geometry::traits::resize<Range>::apply(rng, new_size);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently remove an element from the back of a mutable range.
|
||||
It uses resize().
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline void pop_back(Range & rng)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
|
||||
range::resize(rng, boost::size(rng) - 1);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template <typename It,
|
||||
typename OutIt,
|
||||
bool UseMove = boost::is_convertible
|
||||
<
|
||||
typename std::iterator_traits<It>::value_type &&,
|
||||
typename std::iterator_traits<OutIt>::value_type
|
||||
>::value>
|
||||
struct copy_or_move_impl
|
||||
{
|
||||
static inline OutIt apply(It first, It last, OutIt out)
|
||||
{
|
||||
return std::move(first, last, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename It, typename OutIt>
|
||||
struct copy_or_move_impl<It, OutIt, false>
|
||||
{
|
||||
static inline OutIt apply(It first, It last, OutIt out)
|
||||
{
|
||||
return std::copy(first, last, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename It, typename OutIt>
|
||||
inline OutIt copy_or_move(It first, It last, OutIt out)
|
||||
{
|
||||
return copy_or_move_impl<It, OutIt>::apply(first, last, out);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <typename It, typename OutIt>
|
||||
inline OutIt copy_or_move(It first, It last, OutIt out)
|
||||
{
|
||||
return std::copy(first, last, out);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently remove an element from a mutable range.
|
||||
It uses std::copy() and resize(). Version taking mutable iterators.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_iterator<Range>::type
|
||||
erase(Range & rng,
|
||||
typename boost::range_iterator<Range>::type it)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
|
||||
BOOST_GEOMETRY_ASSERT(it != boost::end(rng));
|
||||
|
||||
typename boost::range_difference<Range>::type const
|
||||
d = std::distance(boost::begin(rng), it);
|
||||
|
||||
typename boost::range_iterator<Range>::type
|
||||
next = it;
|
||||
++next;
|
||||
|
||||
detail::copy_or_move(next, boost::end(rng), it);
|
||||
range::resize(rng, boost::size(rng) - 1);
|
||||
|
||||
// NOTE: In general this should be sufficient:
|
||||
// return it;
|
||||
// But in MSVC using the returned iterator causes
|
||||
// assertion failures when iterator debugging is enabled
|
||||
// Furthermore the code below should work in the case if resize()
|
||||
// invalidates iterators when the container is resized down.
|
||||
return boost::begin(rng) + d;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently remove an element from a mutable range.
|
||||
It uses std::copy() and resize(). Version taking non-mutable iterators.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_iterator<Range>::type
|
||||
erase(Range & rng,
|
||||
typename boost::range_iterator<Range const>::type cit)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
|
||||
|
||||
typename boost::range_iterator<Range>::type
|
||||
it = boost::begin(rng)
|
||||
+ std::distance(boost::const_begin(rng), cit);
|
||||
|
||||
return erase(rng, it);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently remove a range of elements from a mutable range.
|
||||
It uses std::copy() and resize(). Version taking mutable iterators.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_iterator<Range>::type
|
||||
erase(Range & rng,
|
||||
typename boost::range_iterator<Range>::type first,
|
||||
typename boost::range_iterator<Range>::type last)
|
||||
{
|
||||
typename boost::range_difference<Range>::type const
|
||||
diff = std::distance(first, last);
|
||||
BOOST_GEOMETRY_ASSERT(diff >= 0);
|
||||
|
||||
std::size_t const count = static_cast<std::size_t>(diff);
|
||||
BOOST_GEOMETRY_ASSERT(count <= boost::size(rng));
|
||||
|
||||
if ( count > 0 )
|
||||
{
|
||||
typename boost::range_difference<Range>::type const
|
||||
d = std::distance(boost::begin(rng), first);
|
||||
|
||||
detail::copy_or_move(last, boost::end(rng), first);
|
||||
range::resize(rng, boost::size(rng) - count);
|
||||
|
||||
// NOTE: In general this should be sufficient:
|
||||
// return first;
|
||||
// But in MSVC using the returned iterator causes
|
||||
// assertion failures when iterator debugging is enabled
|
||||
// Furthermore the code below should work in the case if resize()
|
||||
// invalidates iterators when the container is resized down.
|
||||
return boost::begin(rng) + d;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently remove a range of elements from a mutable range.
|
||||
It uses std::copy() and resize(). Version taking non-mutable iterators.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_iterator<Range>::type
|
||||
erase(Range & rng,
|
||||
typename boost::range_iterator<Range const>::type cfirst,
|
||||
typename boost::range_iterator<Range const>::type clast)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
|
||||
|
||||
typename boost::range_iterator<Range>::type
|
||||
first = boost::begin(rng)
|
||||
+ std::distance(boost::const_begin(rng), cfirst);
|
||||
typename boost::range_iterator<Range>::type
|
||||
last = boost::begin(rng)
|
||||
+ std::distance(boost::const_begin(rng), clast);
|
||||
|
||||
return erase(rng, first, last);
|
||||
}
|
||||
|
||||
// back_inserter
|
||||
|
||||
template <class Container>
|
||||
class back_insert_iterator
|
||||
: public std::iterator<std::output_iterator_tag, void, void, void, void>
|
||||
{
|
||||
public:
|
||||
typedef Container container_type;
|
||||
|
||||
explicit back_insert_iterator(Container & c)
|
||||
: container(boost::addressof(c))
|
||||
{}
|
||||
|
||||
back_insert_iterator & operator=(typename Container::value_type const& value)
|
||||
{
|
||||
range::push_back(*container, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator & operator* ()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator & operator++ ()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator operator++(int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Container * container;
|
||||
};
|
||||
|
||||
template <typename Range>
|
||||
inline back_insert_iterator<Range> back_inserter(Range & rng)
|
||||
{
|
||||
return back_insert_iterator<Range>(rng);
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::range
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_RANGE_HPP
|
||||
@@ -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
|
||||
@@ -0,0 +1,84 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_SELECT_CALCULATION_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_SELECT_CALCULATION_TYPE_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function selecting the "calculation" type
|
||||
\details Based on two input geometry types, and an input calculation type,
|
||||
(which defaults to void in the calling function), this meta-function
|
||||
selects the most appropriate:
|
||||
- if calculation type is specified, that one is used,
|
||||
- if it is void, the most precise of the two points is used
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename CalculationType>
|
||||
struct select_calculation_type
|
||||
{
|
||||
typedef typename
|
||||
boost::mpl::if_
|
||||
<
|
||||
boost::is_void<CalculationType>,
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type,
|
||||
CalculationType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// alternative version supporting more than 2 Geometries
|
||||
|
||||
template <typename CalculationType,
|
||||
typename Geometry1,
|
||||
typename Geometry2 = void,
|
||||
typename Geometry3 = void>
|
||||
struct select_calculation_type_alt
|
||||
{
|
||||
typedef typename
|
||||
boost::mpl::if_
|
||||
<
|
||||
boost::is_void<CalculationType>,
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Geometry3
|
||||
>::type,
|
||||
CalculationType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_SELECT_CALCULATION_TYPE_HPP
|
||||
@@ -0,0 +1,69 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_SELECT_COORDINATE_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_SELECT_COORDINATE_TYPE_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function selecting the most precise coordinate type
|
||||
of two geometries
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename T1, typename T2 = void, typename T3 = void>
|
||||
struct select_coordinate_type
|
||||
{
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<T1>::type,
|
||||
typename coordinate_type<T2>::type,
|
||||
typename coordinate_type<T3>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct select_coordinate_type<T1, T2, void>
|
||||
{
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<T1>::type,
|
||||
typename coordinate_type<T2>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
struct select_coordinate_type<T1, void, void>
|
||||
{
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<T1>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_SELECT_COORDINATE_TYPE_HPP
|
||||
@@ -0,0 +1,182 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// 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_SELECT_MOST_PRECISE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
|
||||
namespace detail { namespace select_most_precise
|
||||
{
|
||||
|
||||
|
||||
// At least one of the types is non-fundamental. Take that one.
|
||||
// if both are non-fundamental, the type-to-be-selected
|
||||
// is unknown, it should be defined by explicit specialization.
|
||||
template <bool Fundamental1, bool Fundamental2, typename T1, typename T2>
|
||||
struct select_non_fundamental
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct select_non_fundamental<true, false, T1, T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct select_non_fundamental<false, true, T1, T2>
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
|
||||
// Selection of largest type (e.g. int of <short int,int>
|
||||
// It defaults takes the first one, if second is larger, take the second one
|
||||
template <bool SecondLarger, typename T1, typename T2>
|
||||
struct select_largest
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct select_largest<true, T1, T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Selection of floating point and specializations:
|
||||
// both FP or both !FP does never occur...
|
||||
template <bool FP1, bool FP2, typename T1, typename T2>
|
||||
struct select_floating_point
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
|
||||
// ... so if ONE but not both of these types is floating point, take that one
|
||||
template <typename T1, typename T2>
|
||||
struct select_floating_point<true, false, T1, T2>
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct select_floating_point<false, true, T1, T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::select_most_precise
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function to select, of two types, the most accurate type for
|
||||
calculations
|
||||
\ingroup utility
|
||||
\details select_most_precise classes, compares two types on compile time.
|
||||
For example, if an addition must be done with a double and an integer, the
|
||||
result must be a double.
|
||||
If both types are integer, the result can be an integer.
|
||||
\note It is different from the "promote" class, already in boost. That
|
||||
class promotes e.g. a (one) float to a double. This class selects a
|
||||
type from two types. It takes the most accurate, but does not promote
|
||||
afterwards.
|
||||
\note This traits class is completely independant from GGL and might be a
|
||||
separate addition to Boost
|
||||
\note If the input is a non-fundamental type, it might be a calculation
|
||||
type such as a GMP-value or another high precision value. Therefore,
|
||||
if one is non-fundamental, that one is chosen.
|
||||
\note If both types are non-fundamental, the result is indeterminate and
|
||||
currently the first one is chosen.
|
||||
*/
|
||||
template <typename T1, typename T2 = void, typename T3 = void>
|
||||
struct select_most_precise
|
||||
{
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type,
|
||||
T3
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct select_most_precise<T1, T2, void>
|
||||
{
|
||||
static const bool second_larger = sizeof(T2) > sizeof(T1);
|
||||
static const bool one_not_fundamental = !
|
||||
(boost::is_fundamental<T1>::type::value
|
||||
&& boost::is_fundamental<T2>::type::value);
|
||||
|
||||
static const bool both_same =
|
||||
boost::is_floating_point<T1>::type::value
|
||||
== boost::is_floating_point<T2>::type::value;
|
||||
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
one_not_fundamental,
|
||||
typename detail::select_most_precise::select_non_fundamental
|
||||
<
|
||||
boost::is_fundamental<T1>::type::value,
|
||||
boost::is_fundamental<T2>::type::value,
|
||||
T1,
|
||||
T2
|
||||
>::type,
|
||||
typename boost::mpl::if_c
|
||||
<
|
||||
both_same,
|
||||
typename detail::select_most_precise::select_largest
|
||||
<
|
||||
second_larger,
|
||||
T1,
|
||||
T2
|
||||
>::type,
|
||||
typename detail::select_most_precise::select_floating_point
|
||||
<
|
||||
boost::is_floating_point<T1>::type::value,
|
||||
boost::is_floating_point<T2>::type::value,
|
||||
T1,
|
||||
T2
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
struct select_most_precise<T1, void, void>
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
|
||||
@@ -0,0 +1,84 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// 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_TRANSFORM_VARIANT_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_TRANSFORM_VARIANT_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a Sequence type, an MPL lambda
|
||||
expression and an optional Inserter and returns a variant type over
|
||||
the same types as the initial variant type, each transformed using
|
||||
the lambda expression.
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef boost::mpl::vector<int, float, long> types;
|
||||
typedef transform_variant<types, add_pointer<_> > transformed;
|
||||
typedef variant<int*, float*, long*> result;
|
||||
BOOST_MPL_ASSERT(( equal<result, transformed> ));
|
||||
\endcode
|
||||
*/
|
||||
template <typename Sequence, typename Op, typename In = boost::mpl::na>
|
||||
struct transform_variant:
|
||||
make_variant_over<
|
||||
typename boost::mpl::transform<
|
||||
Sequence,
|
||||
Op,
|
||||
In
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a boost::variant type and an MPL lambda
|
||||
expression and returns a variant type over the same types as the
|
||||
initial variant type, each transformed using the lambda expression.
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef variant<int, float, long> variant_type;
|
||||
typedef transform_variant<variant_type, add_pointer<_> > transformed;
|
||||
typedef variant<int*, float*, long*> result;
|
||||
BOOST_MPL_ASSERT(( equal<result, transformed> ));
|
||||
\endcode
|
||||
*/
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Op>
|
||||
struct transform_variant<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Op, boost::mpl::na> :
|
||||
make_variant_over<
|
||||
typename boost::mpl::transform<
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
Op
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_TRANSFORM_VARIANT_HPP
|
||||
Reference in New Issue
Block a user