stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -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
@@ -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
@@ -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