update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 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.
@@ -15,42 +19,10 @@
#define BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP
#include <boost/mpl/if.hpp>
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("<boost/geometry/util/type_traits.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
#include <boost/geometry/util/type_traits.hpp>
#endif // BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP

View File

@@ -0,0 +1,287 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// 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_ALGORITHM_HPP
#define BOOST_GEOMETRY_UTIL_ALGORITHM_HPP
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/util/type_traits_std.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
// Other implementations can be found in the history of this file.
// The discussion and benchmarks can be found here:
// https://github.com/boostorg/geometry/pull/827
// O(logN) version 2
template <std::size_t N>
struct for_each_index_impl2
{
static const std::size_t N1 = N / 2;
static const std::size_t N2 = N - N1;
template <std::size_t Offset, typename UnaryFunction>
constexpr static inline void apply(UnaryFunction& function)
{
for_each_index_impl2<N1>::template apply<Offset>(function);
for_each_index_impl2<N2>::template apply<Offset + N1>(function);
}
};
template <>
struct for_each_index_impl2<3>
{
template <std::size_t Offset, typename UnaryFunction>
constexpr static inline void apply(UnaryFunction& function)
{
function(util::index_constant<Offset>());
function(util::index_constant<Offset + 1>());
function(util::index_constant<Offset + 2>());
}
};
template <>
struct for_each_index_impl2<2>
{
template <std::size_t Offset, typename UnaryFunction>
constexpr static inline void apply(UnaryFunction& function)
{
function(util::index_constant<Offset>());
function(util::index_constant<Offset + 1>());
}
};
template <>
struct for_each_index_impl2<1>
{
template <std::size_t Offset, typename UnaryFunction>
constexpr static inline void apply(UnaryFunction& function)
{
function(util::index_constant<Offset>());
}
};
template <>
struct for_each_index_impl2<0>
{
template <std::size_t Offset, typename UnaryFunction>
constexpr static inline void apply(UnaryFunction& )
{}
};
// Interface
template <std::size_t N, typename UnaryFunction>
constexpr inline UnaryFunction for_each_index(UnaryFunction function)
{
for_each_index_impl2
<
N
>::template apply<0>(function);
return function;
}
template <typename Geometry, typename UnaryFunction>
constexpr inline UnaryFunction for_each_dimension(UnaryFunction function)
{
for_each_index_impl2
<
geometry::dimension<Geometry>::value
>::template apply<0>(function);
return function;
}
// ----------------------------------------------------------------------------
// O(logN) version 2
template <std::size_t N>
struct all_indexes_of_impl2
{
static const std::size_t N1 = N / 2;
static const std::size_t N2 = N - N1;
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return all_indexes_of_impl2<N1>::template apply<Offset>(predicate)
&& all_indexes_of_impl2<N2>::template apply<Offset + N1>(predicate);
}
};
template <>
struct all_indexes_of_impl2<3>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return predicate(util::index_constant<Offset>())
&& predicate(util::index_constant<Offset + 1>())
&& predicate(util::index_constant<Offset + 2>());
}
};
template <>
struct all_indexes_of_impl2<2>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return predicate(util::index_constant<Offset>())
&& predicate(util::index_constant<Offset + 1>());
}
};
template <>
struct all_indexes_of_impl2<1>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return predicate(util::index_constant<Offset>());
}
};
template <>
struct all_indexes_of_impl2<0>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& )
{
return true;
}
};
// Interface
template <std::size_t N, typename UnaryPredicate>
constexpr inline bool all_indexes_of(UnaryPredicate predicate)
{
return all_indexes_of_impl2<N>::template apply<0>(predicate);
}
template <typename Geometry, typename UnaryPredicate>
constexpr inline bool all_dimensions_of(UnaryPredicate predicate)
{
return all_indexes_of_impl2
<
geometry::dimension<Geometry>::value
>::template apply<0>(predicate);
}
// ----------------------------------------------------------------------------
// O(logN) version 2
template <std::size_t N>
struct any_index_of_impl2
{
static const std::size_t N1 = N / 2;
static const std::size_t N2 = N - N1;
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return any_index_of_impl2<N1>::template apply<Offset>(predicate)
|| any_index_of_impl2<N2>::template apply<Offset + N1>(predicate);
}
};
template <>
struct any_index_of_impl2<3>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return predicate(util::index_constant<Offset>())
|| predicate(util::index_constant<Offset + 1>())
|| predicate(util::index_constant<Offset + 2>());
}
};
template <>
struct any_index_of_impl2<2>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return predicate(util::index_constant<Offset>())
|| predicate(util::index_constant<Offset + 1>());
}
};
template <>
struct any_index_of_impl2<1>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& predicate)
{
return predicate(util::index_constant<Offset>());
}
};
template <>
struct any_index_of_impl2<0>
{
template <std::size_t Offset, typename UnaryPredicate>
constexpr static inline bool apply(UnaryPredicate& )
{
return false;
}
};
// Interface
template <std::size_t N, typename UnaryPredicate>
constexpr inline bool any_index_of(UnaryPredicate predicate)
{
return any_index_of_impl2<N>::template apply<0>(predicate);
}
template <typename Geometry, typename UnaryPredicate>
constexpr inline bool any_dimension_of(UnaryPredicate predicate)
{
return any_index_of_impl2
<
geometry::dimension<Geometry>::value
>::template apply<0>(predicate);
}
template <std::size_t N, typename UnaryPredicate>
constexpr inline bool none_index_of(UnaryPredicate predicate)
{
return ! any_index_of_impl2<N>::template apply<0>(predicate);
}
template <typename Geometry, typename UnaryPredicate>
constexpr inline bool none_dimension_of(UnaryPredicate predicate)
{
return ! any_index_of_impl2
<
geometry::dimension<Geometry>::value
>::template apply<0>(predicate);
}
// ----------------------------------------------------------------------------
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_ALGORITHM_HPP

View File

@@ -4,9 +4,8 @@
// 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.
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 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,
@@ -17,36 +16,10 @@
#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>
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("<boost/geometry/util/type_traits.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
#include <boost/geometry/util/type_traits.hpp>
#endif // BOOST_GEOMETRY_UTIL_BARE_TYPE_HPP

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2012 Bruno Lalande, Paris, France.
// Copyright (c) 2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2018-2020.
// Modifications copyright (c) 2018-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -16,12 +16,8 @@
#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/static_assert.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>
@@ -38,17 +34,13 @@ namespace detail
struct default_integral
{
#ifdef BOOST_HAS_LONG_LONG
typedef boost::long_long_type type;
#else
typedef int type;
#endif
typedef long long type;
};
/*!
\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 non-fundamental (user defined e.g. Boost.Multiprecision), 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
*/
@@ -62,25 +54,25 @@ template
struct calculation_type
{
BOOST_STATIC_ASSERT((
boost::is_fundamental
std::is_fundamental
<
DefaultFloatingPointCalculationType
>::type::value
>::value
));
BOOST_STATIC_ASSERT((
boost::is_fundamental
std::is_fundamental
<
DefaultIntegralCalculationType
>::type::value
>::value
));
typedef typename boost::mpl::if_
typedef std::conditional_t
<
boost::is_void<CalculationType>,
typename boost::mpl::if_
std::is_void<CalculationType>::value,
std::conditional_t
<
boost::is_floating_point<Type>,
std::is_floating_point<Type>::value,
typename select_most_precise
<
DefaultFloatingPointCalculationType,
@@ -91,9 +83,9 @@ struct calculation_type
DefaultIntegralCalculationType,
Type
>::type
>::type,
>,
CalculationType
>::type type;
> type;
};
} // namespace detail

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2020.
// Modifications copyright (c) 2015-2020, 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
@@ -18,6 +18,11 @@
#ifndef BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
#define BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
#include <boost/config/pragma_message.hpp>
#if !defined(BOOST_ALLOW_DEPRECATED_HEADERS)
BOOST_PRAGMA_MESSAGE("This header is deprecated.")
#endif
#include <boost/mpl/bind.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/if.hpp>
@@ -46,9 +51,9 @@ namespace util
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> >
pair<boost::mpl::int_<0>, boost::mpl::int_<0> >
> result_types;
BOOST_MPL_ASSERT(( boost::mpl::equal<combinations, result_types> ));
\endcode
*/

View File

@@ -4,10 +4,11 @@
// 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.
// This file was modified by Oracle on 2015-2020.
// Modifications copyright (c) 2015-2020, 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.
@@ -19,6 +20,10 @@
#ifndef BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP
#define BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP
#include <boost/config/pragma_message.hpp>
#if !defined(BOOST_ALLOW_DEPRECATED_HEADERS)
BOOST_PRAGMA_MESSAGE("This header is deprecated.")
#endif
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/fold.hpp>

View File

@@ -0,0 +1,27 @@
// Boost.Geometry
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// 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_CONSTEXPR_HPP
#define BOOST_GEOMETRY_UTIL_CONSTEXPR_HPP
#include <boost/geometry/util/condition.hpp>
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
#define BOOST_GEOMETRY_CONSTEXPR(CONDITION) constexpr (CONDITION)
#else
#define BOOST_GEOMETRY_CONSTEXPR(CONDITION) (BOOST_GEOMETRY_CONDITION(CONDITION))
#endif
#endif // BOOST_GEOMETRY_UTIL_CONSTEXPR_HPP

View File

@@ -28,7 +28,6 @@ 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>

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, 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.
@@ -16,7 +20,6 @@
#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
{
@@ -25,36 +28,31 @@ namespace boost { namespace geometry
namespace detail
{
template <typename Point, int Dimension, int DimensionCount, bool IsConst>
template
<
typename Point,
int Dimension = 0,
int DimensionCount = dimension<Point>::value
>
struct coordinates_scanner
{
template <typename Op>
static inline Op apply(typename add_const_if_c
<
IsConst,
Point
>::type& point, Op operation)
static inline Op apply(Point& point, Op operation)
{
operation.template apply<Point, Dimension>(point);
return coordinates_scanner
<
Point,
Dimension+1,
DimensionCount,
IsConst
Dimension + 1
>::apply(point, operation);
}
};
template <typename Point, int DimensionCount, bool IsConst>
struct coordinates_scanner<Point, DimensionCount, DimensionCount, IsConst>
template <typename Point, int DimensionCount>
struct coordinates_scanner<Point, DimensionCount, DimensionCount>
{
template <typename Op>
static inline Op apply(typename add_const_if_c
<
IsConst,
Point
>::type& , Op operation)
static inline Op apply(Point& , Op operation)
{
return operation;
}
@@ -68,12 +66,7 @@ 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);
detail::coordinates_scanner<Point>::apply(point, operation);
}
template <typename Point, typename Op>
@@ -81,12 +74,7 @@ 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);
return detail::coordinates_scanner<Point const>::apply(point, operation);
}
}} // namespace boost::geometry

View File

@@ -0,0 +1,49 @@
// Boost.Geometry
// Copyright (c) 2023 Barend Gehrels, 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_WITH_INDEX_HPP
#define BOOST_GEOMETRY_UTIL_FOR_EACH_WITH_INDEX_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size_type.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
// Utility function to implement a Kotlin like range based for loop
template <typename Container, typename Function>
inline void for_each_with_index(Container const& container, Function func)
{
typename boost::range_size<Container>::type index = 0;
for (auto it = boost::begin(container); it != boost::end(container); ++it, ++index)
{
func(index, *it);
}
}
template <typename Container, typename Function>
inline void for_each_with_index(Container& container, Function func)
{
typename boost::range_size<Container>::type index = 0;
for (auto it = boost::begin(container); it != boost::end(container); ++it, ++index)
{
func(index, *it);
}
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_FOR_EACH_WITH_INDEX_HPP

View File

@@ -1,8 +1,9 @@
// Boost.Geometry
// Copyright (c) 2015 Oracle and/or its affiliates.
// Copyright (c) 2015-2020 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,7 +12,7 @@
#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 <type_traits>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp>
@@ -19,7 +20,7 @@
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
@@ -43,7 +44,7 @@ bool has_infinite_coordinate(Point const& point)
<
Point,
detail::isinf,
boost::is_floating_point
std::is_floating_point
<
typename coordinate_type<Point>::type
>::value

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2015 Oracle and/or its affiliates.
// Copyright (c) 2015-2020 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
@@ -13,8 +13,7 @@
#define BOOST_GEOMETRY_UTIL_HAS_NAN_COORDINATE_HPP
#include <cstddef>
#include <boost/type_traits/is_floating_point.hpp>
#include <type_traits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -25,7 +24,7 @@
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
@@ -87,7 +86,7 @@ bool has_nan_coordinate(Point const& point)
<
Point,
detail::isnan,
boost::is_floating_point
std::is_floating_point
<
typename coordinate_type<Point>::type
>::value

View File

@@ -1,8 +1,9 @@
// Boost.Geometry
// Copyright (c) 2015 Oracle and/or its affiliates.
// Copyright (c) 2015-2020 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,7 +12,7 @@
#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 <type_traits>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp>
@@ -19,7 +20,7 @@
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
@@ -43,7 +44,7 @@ bool has_non_finite_coordinate(Point const& point)
<
Point,
detail::is_not_finite,
boost::is_floating_point
std::is_floating_point
<
typename coordinate_type<Point>::type
>::value

View File

@@ -4,12 +4,13 @@
// 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, 2018.
// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014-2022.
// Modifications copyright (c) 2014-2022, Oracle and/or its affiliates.
// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -23,6 +24,7 @@
#include <cmath>
#include <limits>
#include <type_traits>
#include <boost/core/ignore_unused.hpp>
@@ -30,8 +32,6 @@
#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>
@@ -86,7 +86,7 @@ inline T bounded(T const& v, T const& lower)
template <typename T,
bool IsFloatingPoint = boost::is_floating_point<T>::value>
bool IsFloatingPoint = std::is_floating_point<T>::value>
struct abs
{
static inline T apply(T const& value)
@@ -120,7 +120,7 @@ struct equals_default_policy
};
template <typename T,
bool IsFloatingPoint = boost::is_floating_point<T>::value>
bool IsFloatingPoint = std::is_floating_point<T>::value>
struct equals_factor_policy
{
equals_factor_policy()
@@ -139,6 +139,12 @@ struct equals_factor_policy
return factor;
}
template <typename E>
void multiply_epsilon(E const& multiplier)
{
factor *= multiplier;
}
T factor;
};
@@ -153,10 +159,12 @@ struct equals_factor_policy<T, false>
{
return T(1);
}
void multiply_epsilon(T const& ) {}
};
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
bool IsFloatingPoint = std::is_floating_point<Type>::value>
struct equals
{
template <typename Policy>
@@ -203,7 +211,7 @@ inline bool equals_by_policy(T1 const& a, T2 const& b, Policy const& policy)
}
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
bool IsFloatingPoint = std::is_floating_point<Type>::value>
struct smaller
{
static inline bool apply(Type const& a, Type const& b)
@@ -221,13 +229,13 @@ struct smaller<Type, true>
{
return false;
}
return ! equals<Type, true>::apply(b, a, equals_default_policy());
}
};
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
bool IsFloatingPoint = std::is_floating_point<Type>::value>
struct smaller_or_equals
{
static inline bool apply(Type const& a, Type const& b)
@@ -252,7 +260,7 @@ struct smaller_or_equals<Type, true>
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
bool IsFloatingPoint = std::is_floating_point<Type>::value>
struct equals_with_epsilon
: public equals<Type, IsFloatingPoint>
{};
@@ -260,7 +268,7 @@ struct equals_with_epsilon
template
<
typename T,
bool IsFundemantal = boost::is_fundamental<T>::value /* false */
bool IsFundemantal = std::is_fundamental<T>::value /* false */
>
struct square_root
{
@@ -352,7 +360,7 @@ struct square_root<T, true>
template
<
typename T,
bool IsFundemantal = boost::is_fundamental<T>::value /* false */
bool IsFundemantal = std::is_fundamental<T>::value /* false */
>
struct modulo
{
@@ -371,7 +379,7 @@ struct modulo
template
<
typename Fundamental,
bool IsIntegral = boost::is_integral<Fundamental>::value
bool IsIntegral = std::is_integral<Fundamental>::value
>
struct modulo_for_fundamental
{
@@ -453,7 +461,7 @@ struct relaxed_epsilon
// 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>
template <typename T, bool IsIntegral = std::is_integral<T>::value>
struct scaled_epsilon
{
static inline T apply(T const& val)
@@ -461,15 +469,26 @@ struct scaled_epsilon
return (std::max)(abs<T>::apply(val), T(1))
* std::numeric_limits<T>::epsilon();
}
static inline T apply(T const& val, T const& eps)
{
return (std::max)(abs<T>::apply(val), T(1))
* eps;
}
};
template <typename T>
struct scaled_epsilon<T, false>
struct scaled_epsilon<T, true>
{
static inline T apply(T const&)
{
return T(0);
}
static inline T apply(T const&, T const&)
{
return T(0);
}
};
// ItoF ItoI FtoF
@@ -506,6 +525,30 @@ struct rounding_cast<Result, Source, true, false>
}
};
template <typename T, bool IsIntegral = std::is_integral<T>::value>
struct divide
{
static inline T apply(T const& n, T const& d)
{
return n / d;
}
};
template <typename T>
struct divide<T, true>
{
static inline T apply(T const& n, T const& d)
{
return n == 0 ? 0
: n < 0
? (d < 0 ? (n + (-d + 1) / 2) / d + 1
: (n + ( d + 1) / 2) / d - 1 )
: (d < 0 ? (n - (-d + 1) / 2) / d - 1
: (n - ( d + 1) / 2) / d + 1 )
;
}
};
} // namespace detail
#endif
@@ -531,6 +574,11 @@ inline T scaled_epsilon(T const& value)
return detail::scaled_epsilon<T>::apply(value);
}
template <typename T>
inline T scaled_epsilon(T const& value, T const& eps)
{
return detail::scaled_epsilon<T>::apply(value, eps);
}
// Maybe replace this by boost equals or so
@@ -616,6 +664,20 @@ inline T r2d()
return conversion_coefficient;
}
/*!
\brief Wraps an angle in the range [-pi, +pi] (both inclusive)
*/
template <typename T>
inline T wrap_azimuth_in_radian(T const& azimuth)
{
static T const pi = geometry::math::pi<T>();
static T const two_pi = geometry::math::two_pi<T>();
T result = azimuth;
while (result > pi) { result -= two_pi; }
while (result < -pi) { result += two_pi; }
return result;
};
#ifndef DOXYGEN_NO_DETAIL
namespace detail {
@@ -714,7 +776,7 @@ sqrt(T const& value)
{
return detail::square_root
<
T, boost::is_fundamental<T>::value
T, std::is_fundamental<T>::value
>::apply(value);
}
@@ -732,7 +794,7 @@ mod(T const& value1, T const& value2)
{
return detail::modulo
<
T, boost::is_fundamental<T>::value
T, std::is_fundamental<T>::value
>::apply(value1, value2);
}
@@ -772,6 +834,17 @@ inline Result rounding_cast(T const& v)
return detail::rounding_cast<Result, T>::apply(v);
}
/*
\brief Short utility to divide. If the division is integer, it rounds the division
to the nearest value, without using floating point calculations
\ingroup utility
*/
template <typename T>
inline T divide(T const& n, T const& d)
{
return detail::divide<T>::apply(n, d);
}
/*!
\brief Evaluate the sine and cosine function with the argument in degrees
\note The results obey exactly the elementary properties of the trigonometric
@@ -786,16 +859,16 @@ inline void sin_cos_degrees(T const& x,
{
// In order to minimize round-off errors, this function exactly reduces
// the argument to the range [-45, 45] before converting it to radians.
T remainder; int quotient;
remainder = math::mod(x, T(360));
quotient = floor(remainder / 90 + T(0.5));
remainder -= 90 * quotient;
T remainder = math::mod(x, T(360));
T const quotient = std::floor(remainder / T(90) + T(0.5));
remainder -= T(90) * quotient;
// Convert to radians.
remainder *= d2r<T>();
T s = sin(remainder), c = cos(remainder);
T const s = sin(remainder);
T const c = cos(remainder);
switch (unsigned(quotient) & 3U)
{
@@ -808,7 +881,8 @@ inline void sin_cos_degrees(T const& x,
// Set sign of 0 results. -0 only produced for sin(-0).
if (x != 0)
{
sinx += T(0); cosx += T(0);
sinx += T(0);
cosx += T(0);
}
}
@@ -816,7 +890,7 @@ inline void sin_cos_degrees(T const& x,
\brief Round off a given angle
*/
template<typename T>
inline T round_angle(T x) {
inline T round_angle(T const& x) {
static const T z = 1/T(16);
if (x == 0)
@@ -832,13 +906,13 @@ inline T round_angle(T x) {
return x < 0 ? -y : y;
}
/*
/*!
\brief Evaluate the polynomial in x using Horner's method.
*/
// TODO: adl1995 - Merge these functions with formulas/area_formulas.hpp
// i.e. place them in one file.
template <typename NT, typename IteratorType>
inline NT horner_evaluate(NT x,
inline NT horner_evaluate(NT const& x,
IteratorType begin,
IteratorType end)
{
@@ -852,13 +926,13 @@ inline NT horner_evaluate(NT x,
return result;
}
/*
/*!
\brief Evaluate the polynomial.
*/
template<typename IteratorType, typename CT>
inline CT polyval(IteratorType first,
IteratorType last,
const CT eps)
CT const& eps)
{
int N = std::distance(first, last) - 1;
int index = 0;

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015-2017, Oracle and/or its affiliates.
// Copyright (c) 2015-2022, 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
@@ -19,7 +19,7 @@
namespace boost { namespace geometry
{
namespace math
namespace math
{
#ifndef DOXYGEN_NO_DETAIL
@@ -37,8 +37,8 @@ private:
static inline bool is_band(CoordinateType const& longitude1,
CoordinateType const& longitude2)
{
return ! math::smaller(math::abs(longitude1 - longitude2),
constants::period());
return math::larger_or_equals(math::abs(longitude1 - longitude2),
constants::period());
}
public:
@@ -91,8 +91,7 @@ public:
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()));
BOOST_GEOMETRY_ASSERT(! math::larger(longitude2 - longitude1, constants::period()));
}
static inline void apply(CoordinateType& longitude1,

View File

@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2015-2017, Oracle and/or its affiliates.
// Copyright (c) 2015-2022, 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
@@ -22,7 +22,7 @@
namespace boost { namespace geometry
{
namespace math
namespace math
{
#ifndef DOXYGEN_NO_DETAIL
@@ -225,14 +225,14 @@ protected:
{
return
math::mod(value + constants::half_period(), constants::period())
- constants::half_period();
- constants::half_period();
}
static inline CoordinateType normalize_down(CoordinateType const& value)
{
return
math::mod(value - constants::half_period(), constants::period())
+ constants::half_period();
+ constants::half_period();
}
public:
@@ -308,12 +308,37 @@ public:
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_or_equals(constants::min_longitude(), longitude));
BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude()));
}
};
template <typename Units, typename CoordinateType>
inline void normalize_angle_loop(CoordinateType& angle)
{
typedef constants_on_spheroid<CoordinateType, Units> constants;
CoordinateType const pi = constants::half_period();
CoordinateType const two_pi = constants::period();
while (angle > pi)
angle -= two_pi;
while (angle <= -pi)
angle += two_pi;
}
template <typename Units, typename CoordinateType>
inline void normalize_angle_cond(CoordinateType& angle)
{
typedef constants_on_spheroid<CoordinateType, Units> constants;
CoordinateType const pi = constants::half_period();
CoordinateType const two_pi = constants::period();
if (angle > pi)
angle -= two_pi;
else if (angle <= -pi)
angle += two_pi;
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
@@ -470,7 +495,7 @@ inline CoordinateType longitude_interval_distance_signed(CoordinateType const& l
dist_a12 = -dist_a12;
dist_a1b = -dist_a1b;
}
return dist_a1b < c0 ? dist_a1b
: dist_a1b > dist_a12 ? dist_a1b - dist_a12
: c0;

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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.
@@ -15,12 +19,18 @@
#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
{
/*!
\brief Flag for iterating a reversible_view in forward or reverse direction
\ingroup views
*/
enum iterate_direction { iterate_forward, iterate_reverse };
template<order_selector Order>
struct order_as_direction
{};

View File

@@ -4,6 +4,9 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2020 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.
@@ -15,13 +18,13 @@
#define BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
#include <type_traits>
#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
@@ -40,25 +43,25 @@ struct parameter_type_of
Method
>::type parameter_types;
typedef typename boost::mpl::if_
typedef std::conditional_t
<
boost::function_types::is_member_function_pointer<Method>,
boost::mpl::int_<1>,
boost::mpl::int_<0>
>::type base_index_type;
boost::function_types::is_member_function_pointer<Method>::value,
std::integral_constant<int, 1>,
std::integral_constant<int, 0>
> base_index_type;
typedef typename boost::mpl::if_c
typedef std::conditional_t
<
Index == 0,
base_index_type,
typename boost::mpl::plus
std::integral_constant
<
base_index_type,
boost::mpl::int_<Index>
>::type
>::type indexed_type;
int,
(base_index_type::value + Index)
>
> indexed_type;
typedef typename boost::remove_reference
typedef typename std::remove_reference
<
typename boost::mpl::at
<

View File

@@ -0,0 +1,633 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2019 Tinko Bartels, Berlin, Germany.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2019 program.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, 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_EXTENSIONS_TRIANGULATION_STRATEGIES_CARTESIAN_DETAIL_PRECISE_MATH_HPP
#define BOOST_GEOMETRY_EXTENSIONS_TRIANGULATION_STRATEGIES_CARTESIAN_DETAIL_PRECISE_MATH_HPP
#include<numeric>
#include<cmath>
#include<limits>
#include<array>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/util/condition.hpp>
// The following code is based on "Adaptive Precision Floating-Point Arithmetic
// and Fast Robust Geometric Predicates" by Richard Shewchuk,
// J. Discrete Comput Geom (1997) 18: 305. https://doi.org/10.1007/PL00009321
namespace boost { namespace geometry
{
namespace detail { namespace precise_math
{
// See Theorem 6, page 6
template
<
typename RealNumber
>
inline std::array<RealNumber, 2> fast_two_sum(RealNumber const a,
RealNumber const b)
{
RealNumber x = a + b;
RealNumber b_virtual = x - a;
return {{x, b - b_virtual}};
}
// See Theorem 7, page 7 - 8
template
<
typename RealNumber
>
inline std::array<RealNumber, 2> two_sum(RealNumber const a,
RealNumber const b)
{
RealNumber x = a + b;
RealNumber b_virtual = x - a;
RealNumber a_virtual = x - b_virtual;
RealNumber b_roundoff = b - b_virtual;
RealNumber a_roundoff = a - a_virtual;
RealNumber y = a_roundoff + b_roundoff;
return {{ x, y }};
}
// See bottom of page 8
template
<
typename RealNumber
>
inline RealNumber two_diff_tail(RealNumber const a,
RealNumber const b,
RealNumber const x)
{
RealNumber b_virtual = a - x;
RealNumber a_virtual = x + b_virtual;
RealNumber b_roundoff = b_virtual - b;
RealNumber a_roundoff = a - a_virtual;
return a_roundoff + b_roundoff;
}
// see bottom of page 8
template
<
typename RealNumber
>
inline std::array<RealNumber, 2> two_diff(RealNumber const a,
RealNumber const b)
{
RealNumber x = a - b;
RealNumber y = two_diff_tail(a, b, x);
return {{ x, y }};
}
// see theorem 18, page 19
template
<
typename RealNumber
>
inline RealNumber two_product_tail(RealNumber const a,
RealNumber const b,
RealNumber const x)
{
return std::fma(a, b, -x);
}
// see theorem 18, page 19
template
<
typename RealNumber
>
inline std::array<RealNumber, 2> two_product(RealNumber const a,
RealNumber const b)
{
RealNumber x = a * b;
RealNumber y = two_product_tail(a, b, x);
return {{ x , y }};
}
// see theorem 12, figure 7, page 11 - 12,
// this is the 2 by 2 case for the corresponding diff-method
// note that this method takes input in descending order of magnitude and
// returns components in ascending order of magnitude
template
<
typename RealNumber
>
inline std::array<RealNumber, 4> two_two_expansion_diff(
std::array<RealNumber, 2> const a,
std::array<RealNumber, 2> const b)
{
std::array<RealNumber, 4> h;
std::array<RealNumber, 2> Qh = two_diff(a[1], b[1]);
h[0] = Qh[1];
Qh = two_sum( a[0], Qh[0] );
RealNumber _j = Qh[0];
Qh = two_diff(Qh[1], b[0]);
h[1] = Qh[1];
Qh = two_sum( _j, Qh[0] );
h[2] = Qh[1];
h[3] = Qh[0];
return h;
}
// see theorem 13, figure 8. This implementation uses zero elimination as
// suggested on page 17, second to last paragraph. Returns the number of
// non-zero components in the result and writes the result to h.
// the merger into a single sequence g is done implicitly
template
<
typename RealNumber,
std::size_t InSize1,
std::size_t InSize2,
std::size_t OutSize
>
inline int fast_expansion_sum_zeroelim(
std::array<RealNumber, InSize1> const& e,
std::array<RealNumber, InSize2> const& f,
std::array<RealNumber, OutSize> & h,
int m = InSize1,
int n = InSize2)
{
std::array<RealNumber, 2> Qh;
int i_e = 0;
int i_f = 0;
int i_h = 0;
if (std::abs(f[0]) > std::abs(e[0]))
{
Qh[0] = e[i_e++];
}
else
{
Qh[0] = f[i_f++];
}
i_h = 0;
if ((i_e < m) && (i_f < n))
{
if (std::abs(f[i_f]) > std::abs(e[i_e]))
{
Qh = fast_two_sum(e[i_e++], Qh[0]);
}
else
{
Qh = fast_two_sum(f[i_f++], Qh[0]);
}
if (Qh[1] != 0.0)
{
h[i_h++] = Qh[1];
}
while ((i_e < m) && (i_f < n))
{
if (std::abs(f[i_f]) > std::abs(e[i_e]))
{
Qh = two_sum(Qh[0], e[i_e++]);
}
else
{
Qh = two_sum(Qh[0], f[i_f++]);
}
if (Qh[1] != 0.0)
{
h[i_h++] = Qh[1];
}
}
}
while (i_e < m)
{
Qh = two_sum(Qh[0], e[i_e++]);
if (Qh[1] != 0.0)
{
h[i_h++] = Qh[1];
}
}
while (i_f < n)
{
Qh = two_sum(Qh[0], f[i_f++]);
if (Qh[1] != 0.0)
{
h[i_h++] = Qh[1];
}
}
if ((Qh[0] != 0.0) || (i_h == 0))
{
h[i_h++] = Qh[0];
}
return i_h;
}
// see theorem 19, figure 13, page 20 - 21. This implementation uses zero
// elimination as suggested on page 17, second to last paragraph. Returns the
// number of non-zero components in the result and writes the result to h.
template
<
typename RealNumber,
std::size_t InSize
>
inline int scale_expansion_zeroelim(
std::array<RealNumber, InSize> const& e,
RealNumber const b,
std::array<RealNumber, 2 * InSize> & h,
int e_non_zeros = InSize)
{
std::array<RealNumber, 2> Qh = two_product(e[0], b);
int i_h = 0;
if (Qh[1] != 0)
{
h[i_h++] = Qh[1];
}
for (int i_e = 1; i_e < e_non_zeros; i_e++)
{
std::array<RealNumber, 2> Tt = two_product(e[i_e], b);
Qh = two_sum(Qh[0], Tt[1]);
if (Qh[1] != 0)
{
h[i_h++] = Qh[1];
}
Qh = fast_two_sum(Tt[0], Qh[0]);
if (Qh[1] != 0)
{
h[i_h++] = Qh[1];
}
}
if ((Qh[0] != 0.0) || (i_h == 0))
{
h[i_h++] = Qh[0];
}
return i_h;
}
template<typename RealNumber>
struct vec2d
{
RealNumber x;
RealNumber y;
};
template
<
typename RealNumber,
std::size_t Robustness
>
inline RealNumber orient2dtail(vec2d<RealNumber> const& p1,
vec2d<RealNumber> const& p2,
vec2d<RealNumber> const& p3,
std::array<RealNumber, 2>& t1,
std::array<RealNumber, 2>& t2,
std::array<RealNumber, 2>& t3,
std::array<RealNumber, 2>& t4,
std::array<RealNumber, 2>& t5_01,
std::array<RealNumber, 2>& t6_01,
RealNumber const& magnitude)
{
t5_01[1] = two_product_tail(t1[0], t2[0], t5_01[0]);
t6_01[1] = two_product_tail(t3[0], t4[0], t6_01[0]);
std::array<RealNumber, 4> tA_03 = two_two_expansion_diff(t5_01, t6_01);
RealNumber det = std::accumulate(tA_03.begin(), tA_03.end(), static_cast<RealNumber>(0));
if (BOOST_GEOMETRY_CONDITION(Robustness == 1))
{
return det;
}
// see p.39, mind the different definition of epsilon for error bound
RealNumber B_relative_bound =
(1 + 3 * std::numeric_limits<RealNumber>::epsilon())
* std::numeric_limits<RealNumber>::epsilon();
RealNumber absolute_bound = B_relative_bound * magnitude;
if (std::abs(det) >= absolute_bound)
{
return det; //B estimate
}
t1[1] = two_diff_tail(p1.x, p3.x, t1[0]);
t2[1] = two_diff_tail(p2.y, p3.y, t2[0]);
t3[1] = two_diff_tail(p1.y, p3.y, t3[0]);
t4[1] = two_diff_tail(p2.x, p3.x, t4[0]);
if ((t1[1] == 0) && (t3[1] == 0) && (t2[1] == 0) && (t4[1] == 0))
{
return det; //If all tails are zero, there is noething else to compute
}
RealNumber sub_bound =
(1.5 + 2 * std::numeric_limits<RealNumber>::epsilon())
* std::numeric_limits<RealNumber>::epsilon();
// see p.39, mind the different definition of epsilon for error bound
RealNumber C_relative_bound =
(2.25 + 8 * std::numeric_limits<RealNumber>::epsilon())
* std::numeric_limits<RealNumber>::epsilon()
* std::numeric_limits<RealNumber>::epsilon();
absolute_bound = C_relative_bound * magnitude + sub_bound * std::abs(det);
det += (t1[0] * t2[1] + t2[0] * t1[1]) - (t3[0] * t4[1] + t4[0] * t3[1]);
if (Robustness == 2 || std::abs(det) >= absolute_bound)
{
return det; //C estimate
}
std::array<RealNumber, 8> D_left;
int D_left_nz;
{
std::array<RealNumber, 2> t5_23 = two_product(t1[1], t2[0]);
std::array<RealNumber, 2> t6_23 = two_product(t3[1], t4[0]);
std::array<RealNumber, 4> tA_47 = two_two_expansion_diff(t5_23, t6_23);
D_left_nz = fast_expansion_sum_zeroelim(tA_03, tA_47, D_left);
}
std::array<RealNumber, 8> D_right;
int D_right_nz;
{
std::array<RealNumber, 2> t5_45 = two_product(t1[0], t2[1]);
std::array<RealNumber, 2> t6_45 = two_product(t3[0], t4[1]);
std::array<RealNumber, 4> tA_8_11 = two_two_expansion_diff(t5_45, t6_45);
std::array<RealNumber, 2> t5_67 = two_product(t1[1], t2[1]);
std::array<RealNumber, 2> t6_67 = two_product(t3[1], t4[1]);
std::array<RealNumber, 4> tA_12_15 = two_two_expansion_diff(t5_67, t6_67);
D_right_nz = fast_expansion_sum_zeroelim(tA_8_11, tA_12_15, D_right);
}
std::array<RealNumber, 16> D;
int D_nz = fast_expansion_sum_zeroelim(D_left, D_right, D, D_left_nz, D_right_nz);
// only return component of highest magnitude because we mostly care about the sign.
return(D[D_nz - 1]);
}
// see page 38, Figure 21 for the calculations, notation follows the notation
// in the figure.
template
<
typename RealNumber,
std::size_t Robustness = 3,
typename EpsPolicy
>
inline RealNumber orient2d(vec2d<RealNumber> const& p1,
vec2d<RealNumber> const& p2,
vec2d<RealNumber> const& p3,
EpsPolicy& eps_policy)
{
std::array<RealNumber, 2> t1, t2, t3, t4;
t1[0] = p1.x - p3.x;
t2[0] = p2.y - p3.y;
t3[0] = p1.y - p3.y;
t4[0] = p2.x - p3.x;
eps_policy = EpsPolicy(t1[0], t2[0], t3[0], t4[0]);
std::array<RealNumber, 2> t5_01, t6_01;
t5_01[0] = t1[0] * t2[0];
t6_01[0] = t3[0] * t4[0];
RealNumber det = t5_01[0] - t6_01[0];
if (BOOST_GEOMETRY_CONDITION(Robustness == 0))
{
return det;
}
RealNumber const magnitude = std::abs(t5_01[0]) + std::abs(t6_01[0]);
// see p.39, mind the different definition of epsilon for error bound
RealNumber const A_relative_bound =
(1.5 + 4 * std::numeric_limits<RealNumber>::epsilon())
* std::numeric_limits<RealNumber>::epsilon();
RealNumber absolute_bound = A_relative_bound * magnitude;
if ( std::abs(det) >= absolute_bound )
{
return det; //A estimate
}
if ( (t5_01[0] > 0 && t6_01[0] <= 0) || (t5_01[0] < 0 && t6_01[0] >= 0) )
{
//if diagonal and antidiagonal have different sign, the sign of det is
//obvious
return det;
}
return orient2dtail<RealNumber, Robustness>(p1, p2, p3, t1, t2, t3, t4,
t5_01, t6_01, magnitude);
}
// This method adaptively computes increasingly precise approximations of the following
// determinant using Laplace expansion along the last column.
// det A =
// | p1_x - p4_x p1_y - p4_y ( p1_x - p4_x ) ^ 2 + ( p1_y - p4_y ) ^ 2 |
// | p2_x - p4_x p2_y - p4_y ( p2_x - p4_x ) ^ 2 + ( p1_y - p4_y ) ^ 2 |
// | p3_x - p4_x p3_y - p4_y ( p3_x - p4_x ) ^ 2 + ( p3_y - p4_y ) ^ 2 |
// = a_13 * C_13 + a_23 * C_23 + a_33 * C_33
// where a_ij is the i-j-entry and C_ij is the i_j Cofactor
template
<
typename RealNumber,
std::size_t Robustness = 2
>
RealNumber incircle(std::array<RealNumber, 2> const& p1,
std::array<RealNumber, 2> const& p2,
std::array<RealNumber, 2> const& p3,
std::array<RealNumber, 2> const& p4)
{
RealNumber A_11 = p1[0] - p4[0];
RealNumber A_21 = p2[0] - p4[0];
RealNumber A_31 = p3[0] - p4[0];
RealNumber A_12 = p1[1] - p4[1];
RealNumber A_22 = p2[1] - p4[1];
RealNumber A_32 = p3[1] - p4[1];
std::array<RealNumber, 2> A_21_x_A_32,
A_31_x_A_22,
A_31_x_A_12,
A_11_x_A_32,
A_11_x_A_22,
A_21_x_A_12;
A_21_x_A_32[0] = A_21 * A_32;
A_31_x_A_22[0] = A_31 * A_22;
RealNumber A_13 = A_11 * A_11 + A_12 * A_12;
A_31_x_A_12[0] = A_31 * A_12;
A_11_x_A_32[0] = A_11 * A_32;
RealNumber A_23 = A_21 * A_21 + A_22 * A_22;
A_11_x_A_22[0] = A_11 * A_22;
A_21_x_A_12[0] = A_21 * A_12;
RealNumber A_33 = A_31 * A_31 + A_32 * A_32;
RealNumber det = A_13 * (A_21_x_A_32[0] - A_31_x_A_22[0])
+ A_23 * (A_31_x_A_12[0] - A_11_x_A_32[0])
+ A_33 * (A_11_x_A_22[0] - A_21_x_A_12[0]);
if(Robustness == 0) return det;
RealNumber magnitude =
(std::abs(A_21_x_A_32[0]) + std::abs(A_31_x_A_22[0])) * A_13
+ (std::abs(A_31_x_A_12[0]) + std::abs(A_11_x_A_32[0])) * A_23
+ (std::abs(A_11_x_A_22[0]) + std::abs(A_21_x_A_12[0])) * A_33;
RealNumber A_relative_bound =
(5 + 24 * std::numeric_limits<RealNumber>::epsilon())
* std::numeric_limits<RealNumber>::epsilon();
RealNumber absolute_bound = A_relative_bound * magnitude;
if (std::abs(det) > absolute_bound)
{
return det;
}
// (p2_x - p4_x) * (p3_y - p4_y)
A_21_x_A_32[1] = two_product_tail(A_21, A_32, A_21_x_A_32[0]);
// (p3_x - p4_x) * (p2_y - p4_y)
A_31_x_A_22[1] = two_product_tail(A_31, A_22, A_31_x_A_22[0]);
// (bx - dx) * (cy - dy) - (cx - dx) * (by - dy)
std::array<RealNumber, 4> C_13 = two_two_expansion_diff(A_21_x_A_32, A_31_x_A_22);
std::array<RealNumber, 8> C_13_x_A11;
// ( (bx - dx) * (cy - dy) - (cx - dx) * (by - dy) ) * ( ax - dx )
int C_13_x_A11_nz = scale_expansion_zeroelim(C_13, A_11, C_13_x_A11);
std::array<RealNumber, 16> C_13_x_A11_sq;
// ( (bx - dx) * (cy - dy) - (cx - dx) * (by - dy) ) * ( ax - dx ) * (ax - dx)
int C_13_x_A11_sq_nz = scale_expansion_zeroelim(C_13_x_A11,
A_11,
C_13_x_A11_sq,
C_13_x_A11_nz);
std::array<RealNumber, 8> C_13_x_A12;
// ( (bx - dx) * (cy - dy) - (cx - dx) * (by - dy) ) * ( ay - dy )
int C_13_x_A12_nz = scale_expansion_zeroelim(C_13, A_12, C_13_x_A12);
std::array<RealNumber, 16> C_13_x_A12_sq;
// ( (bx - dx) * (cy - dy) - (cx - dx) * (by - dy) ) * ( ay - dy ) * ( ay - dy )
int C_13_x_A12_sq_nz = scale_expansion_zeroelim(C_13_x_A12, A_12,
C_13_x_A12_sq,
C_13_x_A12_nz);
std::array<RealNumber, 32> A_13_x_C13;
// ( (bx - dx) * (cy - dy) - (cx - dx) * (by - dy) )
// * ( ( ay - dy ) * ( ay - dy ) + ( ax - dx ) * (ax - dx) )
int A_13_x_C13_nz = fast_expansion_sum_zeroelim(C_13_x_A11_sq,
C_13_x_A12_sq,
A_13_x_C13,
C_13_x_A11_sq_nz,
C_13_x_A12_sq_nz);
// (cx - dx) * (ay - dy)
A_31_x_A_12[1] = two_product_tail(A_31, A_12, A_31_x_A_12[0]);
// (ax - dx) * (cy - dy)
A_11_x_A_32[1] = two_product_tail(A_11, A_32, A_11_x_A_32[0]);
// (cx - dx) * (ay - dy) - (ax - dx) * (cy - dy)
std::array<RealNumber, 4> C_23 = two_two_expansion_diff(A_31_x_A_12,
A_11_x_A_32);
std::array<RealNumber, 8> C_23_x_A_21;
// ( (cx - dx) * (ay - dy) - (ax - dx) * (cy - dy) ) * ( bx - dx )
int C_23_x_A_21_nz = scale_expansion_zeroelim(C_23, A_21, C_23_x_A_21);
std::array<RealNumber, 16> C_23_x_A_21_sq;
// ( (cx - dx) * (ay - dy) - (ax - dx) * (cy - dy) ) * ( bx - dx ) * ( bx - dx )
int C_23_x_A_21_sq_nz = scale_expansion_zeroelim(C_23_x_A_21, A_21,
C_23_x_A_21_sq,
C_23_x_A_21_nz);
std::array<RealNumber, 8> C_23_x_A_22;
// ( (cx - dx) * (ay - dy) - (ax - dx) * (cy - dy) ) * ( by - dy )
int C_23_x_A_22_nz = scale_expansion_zeroelim(C_23, A_22, C_23_x_A_22);
std::array<RealNumber, 16> C_23_x_A_22_sq;
// ( (cx - dx) * (ay - dy) - (ax - dx) * (cy - dy) ) * ( by - dy ) * ( by - dy )
int C_23_x_A_22_sq_nz = scale_expansion_zeroelim(C_23_x_A_22, A_22,
C_23_x_A_22_sq,
C_23_x_A_22_nz);
std::array<RealNumber, 32> A_23_x_C_23;
// ( (cx - dx) * (ay - dy) - (ax - dx) * (cy - dy) )
// * ( ( bx - dx ) * ( bx - dx ) + ( by - dy ) * ( by - dy ) )
int A_23_x_C_23_nz = fast_expansion_sum_zeroelim(C_23_x_A_21_sq,
C_23_x_A_22_sq,
A_23_x_C_23,
C_23_x_A_21_sq_nz,
C_23_x_A_22_sq_nz);
// (ax - dx) * (by - dy)
A_11_x_A_22[1] = two_product_tail(A_11, A_22, A_11_x_A_22[0]);
// (bx - dx) * (ay - dy)
A_21_x_A_12[1] = two_product_tail(A_21, A_12, A_21_x_A_12[0]);
// (ax - dx) * (by - dy) - (bx - dx) * (ay - dy)
std::array<RealNumber, 4> C_33 = two_two_expansion_diff(A_11_x_A_22,
A_21_x_A_12);
std::array<RealNumber, 8> C_33_x_A31;
// ( (ax - dx) * (by - dy) - (bx - dx) * (ay - dy) ) * ( cx - dx )
int C_33_x_A31_nz = scale_expansion_zeroelim(C_33, A_31, C_33_x_A31);
std::array<RealNumber, 16> C_33_x_A31_sq;
// ( (ax - dx) * (by - dy) - (bx - dx) * (ay - dy) ) * ( cx - dx ) * ( cx - dx )
int C_33_x_A31_sq_nz = scale_expansion_zeroelim(C_33_x_A31, A_31,
C_33_x_A31_sq,
C_33_x_A31_nz);
std::array<RealNumber, 8> C_33_x_A_32;
// ( (ax - dx) * (by - dy) - (bx - dx) * (ay - dy) ) * ( cy - dy )
int C_33_x_A_32_nz = scale_expansion_zeroelim(C_33, A_32, C_33_x_A_32);
std::array<RealNumber, 16> C_33_x_A_32_sq;
// ( (ax - dx) * (by - dy) - (bx - dx) * (ay - dy) ) * ( cy - dy ) * ( cy - dy )
int C_33_x_A_32_sq_nz = scale_expansion_zeroelim(C_33_x_A_32, A_32,
C_33_x_A_32_sq,
C_33_x_A_32_nz);
std::array<RealNumber, 32> A_33_x_C_33;
int A_33_x_C_33_nz = fast_expansion_sum_zeroelim(C_33_x_A31_sq,
C_33_x_A_32_sq,
A_33_x_C_33,
C_33_x_A31_sq_nz,
C_33_x_A_32_sq_nz);
std::array<RealNumber, 64> A_13_x_C13_p_A_13_x_C13;
int A_13_x_C13_p_A_13_x_C13_nz = fast_expansion_sum_zeroelim(
A_13_x_C13, A_23_x_C_23,
A_13_x_C13_p_A_13_x_C13,
A_13_x_C13_nz,
A_23_x_C_23_nz);
std::array<RealNumber, 96> det_expansion;
int det_expansion_nz = fast_expansion_sum_zeroelim(
A_13_x_C13_p_A_13_x_C13,
A_33_x_C_33,
det_expansion,
A_13_x_C13_p_A_13_x_C13_nz,
A_33_x_C_33_nz);
det = std::accumulate(det_expansion.begin(),
det_expansion.begin() + det_expansion_nz,
static_cast<RealNumber>(0));
if(Robustness == 1) return det;
RealNumber B_relative_bound =
(2 + 12 * std::numeric_limits<RealNumber>::epsilon())
* std::numeric_limits<RealNumber>::epsilon();
absolute_bound = B_relative_bound * magnitude;
if (std::abs(det) >= absolute_bound)
{
return det;
}
RealNumber A_11tail = two_diff_tail(p1[0], p4[0], A_11);
RealNumber A_12tail = two_diff_tail(p1[1], p4[1], A_12);
RealNumber A_21tail = two_diff_tail(p2[0], p4[0], A_21);
RealNumber A_22tail = two_diff_tail(p2[1], p4[1], A_22);
RealNumber A_31tail = two_diff_tail(p3[0], p4[0], A_31);
RealNumber A_32tail = two_diff_tail(p3[1], p4[1], A_32);
if ((A_11tail == 0) && (A_21tail == 0) && (A_31tail == 0)
&& (A_12tail == 0) && (A_22tail == 0) && (A_32tail == 0))
{
return det;
}
// RealNumber sub_bound = (1.5 + 2.0 * std::numeric_limits<RealNumber>::epsilon())
// * std::numeric_limits<RealNumber>::epsilon();
// RealNumber C_relative_bound = (11.0 + 72.0 * std::numeric_limits<RealNumber>::epsilon())
// * std::numeric_limits<RealNumber>::epsilon()
// * std::numeric_limits<RealNumber>::epsilon();
//absolute_bound = C_relative_bound * magnitude + sub_bound * std::abs(det);
det += ((A_11 * A_11 + A_12 * A_12) * ((A_21 * A_32tail + A_32 * A_21tail)
- (A_22 * A_31tail + A_31 * A_22tail))
+ 2 * (A_11 * A_11tail + A_12 * A_12tail) * (A_21 * A_32 - A_22 * A_31))
+ ((A_21 * A_21 + A_22 * A_22) * ((A_31 * A_12tail + A_12 * A_31tail)
- (A_32 * A_11tail + A_11 * A_32tail))
+ 2 * (A_21 * A_21tail + A_22 * A_22tail) * (A_31 * A_12 - A_32 * A_11))
+ ((A_31 * A_31 + A_32 * A_32) * ((A_11 * A_22tail + A_22 * A_11tail)
- (A_12 * A_21tail + A_21 * A_12tail))
+ 2 * (A_31 * A_31tail + A_32 * A_32tail) * (A_11 * A_22 - A_12 * A_21));
//if (std::abs(det) >= absolute_bound)
//{
return det;
//}
}
}} // namespace detail::precise_math
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_EXTENSIONS_TRIANGULATION_STRATEGIES_CARTESIAN_DETAIL_PRECISE_MATH_HPP

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 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.
@@ -14,37 +18,9 @@
#ifndef BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
#define BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("boost/geometry/core/coordinate_promotion.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
#include <boost/geometry/core/coordinate_promotion.hpp>
#endif // BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015, Oracle and/or its affiliates.
// Copyright (c) 2015-2020, 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
@@ -14,26 +15,15 @@
// 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>
#include <type_traits>
#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
{
@@ -46,7 +36,7 @@ namespace detail { namespace promote_integral
template
<
typename T,
bool IsFundamental = boost::is_fundamental<T>::type::value
bool IsFundamental = std::is_fundamental<T>::value
>
struct bit_size
{};
@@ -55,7 +45,7 @@ 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))>
: std::integral_constant<std::size_t, (CHAR_BIT * sizeof(T))>
{};
@@ -81,46 +71,40 @@ struct bit_size
ExpressionTemplates
>,
false
> : boost::mpl::size_t<MaxSize>
>
: std::integral_constant<std::size_t, MaxSize>
{};
#endif // BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
template
<
typename T,
typename Iterator,
typename EndIterator,
std::size_t MinSize
>
template <typename T, std::size_t MinSize, typename ...Ts>
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;
};
template <typename T, std::size_t MinSize, typename CurrentT, typename ...Ts>
struct promote_to_larger<T, MinSize, CurrentT, Ts...>
{
typedef std::conditional_t
<
(bit_size<CurrentT>::value >= MinSize),
CurrentT,
typename promote_to_larger<T, MinSize, Ts...>::type
> type;
};
template <typename ...Ts>
struct integral_types {};
template <typename T, std::size_t MinSize, typename ...Ts>
struct promote_to_larger<T, MinSize, integral_types<Ts...>>
: promote_to_larger<T, MinSize, Ts...>
{};
}} // namespace detail::promote_integral
#endif // DOXYGEN_NO_DETAIL
@@ -135,14 +119,14 @@ struct promote_to_larger<T, EndIterator, EndIterator, MinSize>
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
short, int, long, long long, 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
unsigned long long, boost::uint128_t
if T is promoted to an unsigned type.
By default an unsigned type is promoted to a signed type.
@@ -161,9 +145,6 @@ struct promote_to_larger<T, EndIterator, EndIterator, MinSize>
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
@@ -173,31 +154,31 @@ template
typename T,
bool PromoteUnsignedToUnsigned = false,
bool UseCheckedInteger = false,
bool IsIntegral = boost::is_integral<T>::type::value
bool IsIntegral = std::is_integral<T>::value
>
class promote_integral
{
private:
static bool const is_unsigned = boost::is_unsigned<T>::type::value;
static bool const is_unsigned = std::is_unsigned<T>::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
typedef std::conditional_t
<
UseCheckedInteger,
boost::integral_constant
std::integral_constant
<
boost::multiprecision::cpp_int_check_type,
boost::multiprecision::checked
>,
boost::integral_constant
std::integral_constant
<
boost::multiprecision::cpp_int_check_type,
boost::multiprecision::unchecked
>
>::type check_policy_type;
> check_policy_type;
// Meta-function to get the multiprecision integer type for the
// given size and sign type (signed/unsigned)
@@ -229,26 +210,26 @@ private:
// * 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
typedef std::conditional_t
<
(PromoteUnsignedToUnsigned && is_unsigned),
boost::mpl::size_t<(2 * bit_size_type::value)>,
typename boost::mpl::if_c
std::integral_constant<std::size_t, (2 * bit_size_type::value)>,
std::conditional_t
<
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;
std::integral_constant<std::size_t, (2 * bit_size_type::value + 1)>,
std::integral_constant<std::size_t, (2 * bit_size_type::value - 1)>
>
> min_bit_size_type;
// Define the list of signed integral types we are going to use
// for promotion
typedef boost::mpl::list
typedef detail::promote_integral::integral_types
<
short, int, long
#if defined(BOOST_HAS_LONG_LONG)
, boost::long_long_type
#endif
short,
int,
long,
long long
#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
, boost::int128_type
#endif
@@ -263,12 +244,13 @@ private:
// Define the list of unsigned integral types we are going to use
// for promotion
typedef boost::mpl::list
typedef detail::promote_integral::integral_types
<
unsigned short, unsigned int, unsigned long, std::size_t
#if defined(BOOST_HAS_LONG_LONG)
, boost::ulong_long_type
#endif
unsigned short,
unsigned int,
unsigned long,
std::size_t,
unsigned long long
#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
, boost::uint128_type
#endif
@@ -284,20 +266,19 @@ private:
// 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
typedef std::conditional_t
<
(is_unsigned && PromoteUnsignedToUnsigned),
unsigned_integral_types,
signed_integral_types
>::type integral_types;
> 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
min_bit_size_type::value,
integral_types
>::type type;
};

View File

@@ -1,74 +1,87 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// 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.
// This file was modified by Oracle on 2013-2021.
// Modifications copyright (c) 2013-2021 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)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
#include <algorithm>
#include <iterator>
#include <type_traits>
#include <boost/concept_check.hpp>
#include <boost/config.hpp>
#include <boost/core/addressof.hpp>
#include <boost/mpl/has_xxx.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/has_range_iterator.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
namespace boost { namespace geometry { namespace range
{
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
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category)
template <typename T>
struct is_iterator
: std::integral_constant
<
bool,
has_iterator_category
<
std::iterator_traits<T>
>::value
>
{};
template <typename T, bool HasIterator = boost::has_range_iterator<T>::value>
struct is_range_impl
: is_iterator
<
typename boost::range_iterator<T>::type
>
{};
template <typename T>
struct is_range_impl<T, false>
: std::false_type
{};
template <typename T>
struct is_range
: is_range_impl<T>
{};
template <typename Range, typename T = void>
using enable_if_mutable_t = std::enable_if_t
<
(! std::is_const<std::remove_reference_t<Range>>::value),
T
>;
} // 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.
@@ -76,24 +89,13 @@ pos(RandomAccessRange const& rng,
*/
template <typename RandomAccessRange>
inline typename boost::range_iterator<RandomAccessRange>::type
pos(RandomAccessRange & rng,
pos(RandomAccessRange && rng,
typename boost::range_size<RandomAccessRange>::type i)
{
BOOST_RANGE_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<RandomAccessRange>));
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);
return boost::begin(rng)
+ static_cast<typename boost::range_difference<RandomAccessRange>::type>(i);
}
/*!
@@ -102,23 +104,10 @@ at(RandomAccessRange const& rng,
*/
template <typename RandomAccessRange>
inline typename boost::range_reference<RandomAccessRange>::type
at(RandomAccessRange & rng,
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);
return *pos(rng, i);
}
/*!
@@ -127,38 +116,24 @@ front(Range const& rng)
*/
template <typename Range>
inline typename boost::range_reference<Range>::type
front(Range & rng)
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)
back(BidirectionalRange && rng)
{
BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept<BidirectionalRange>));
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *(boost::rbegin(rng));
auto it = boost::end(rng);
return *(--it);
}
@@ -167,11 +142,17 @@ back(BidirectionalRange & rng)
It uses traits::clear<>.
\ingroup utility
*/
template <typename Range>
inline void clear(Range & rng)
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
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);
geometry::traits::clear
<
std::remove_reference_t<Range>
>::apply(rng);
}
/*!
@@ -179,11 +160,56 @@ inline void clear(Range & rng)
It uses boost::geometry::traits::push_back<>.
\ingroup utility
*/
template <typename Range>
inline void push_back(Range & rng,
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void push_back(Range && rng,
typename boost::range_value<Range>::type const& value)
{
geometry::traits::push_back<Range>::apply(rng, value);
geometry::traits::push_back
<
std::remove_reference_t<Range>
>::apply(rng, value);
}
/*!
\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,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void push_back(Range && rng,
typename boost::range_value<Range>::type && value)
{
geometry::traits::push_back
<
std::remove_reference_t<Range>
>::apply(rng, std::move(value));
}
/*!
\brief Short utility to conveniently insert a new element at the end of a mutable range.
It uses boost::geometry::traits::emplace_back<>.
\ingroup utility
*/
template
<
typename Range,
typename ...Args,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void emplace_back(Range && rng, Args &&... args)
{
geometry::traits::emplace_back
<
std::remove_reference_t<Range>
>::apply(rng, std::forward<Args>(args)...);
}
/*!
@@ -191,80 +217,48 @@ inline void push_back(Range & rng,
It uses boost::geometry::traits::resize<>.
\ingroup utility
*/
template <typename Range>
inline void resize(Range & rng,
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void resize(Range && rng,
typename boost::range_size<Range>::type new_size)
{
geometry::traits::resize<Range>::apply(rng, new_size);
geometry::traits::resize
<
std::remove_reference_t<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)
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
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.
It uses std::move() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
erase(Range && rng,
typename boost::range_iterator<Range>::type it)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
@@ -277,7 +271,7 @@ erase(Range & rng,
next = it;
++next;
detail::copy_or_move(next, boost::end(rng), it);
std::move(next, boost::end(rng), it);
range::resize(rng, boost::size(rng) - 1);
// NOTE: In general this should be sufficient:
@@ -291,13 +285,17 @@ erase(Range & rng,
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking non-mutable iterators.
It uses std::move() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range const>::type cit)
erase(Range && rng,
typename boost::range_iterator<std::remove_reference_t<Range> const>::type cit)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
@@ -305,17 +303,21 @@ erase(Range & rng,
it = boost::begin(rng)
+ std::distance(boost::const_begin(rng), cit);
return erase(rng, it);
return range::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.
It uses std::move() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
erase(Range && rng,
typename boost::range_iterator<Range>::type first,
typename boost::range_iterator<Range>::type last)
{
@@ -325,13 +327,13 @@ erase(Range & rng,
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);
std::move(last, boost::end(rng), first);
range::resize(rng, boost::size(rng) - count);
// NOTE: In general this should be sufficient:
@@ -348,14 +350,18 @@ erase(Range & rng,
/*!
\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.
It uses std::move() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
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)
erase(Range && rng,
typename boost::range_iterator<std::remove_reference_t<Range> const>::type cfirst,
typename boost::range_iterator<std::remove_reference_t<Range> const>::type clast)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
@@ -366,7 +372,7 @@ erase(Range & rng,
last = boost::begin(rng)
+ std::distance(boost::const_begin(rng), clast);
return erase(rng, first, last);
return range::erase(rng, first, last);
}
// back_inserter
@@ -393,6 +399,12 @@ public:
return *this;
}
back_insert_iterator & operator=(typename Container::value_type && value)
{
range::push_back(*container, std::move(value));
return *this;
}
back_insert_iterator & operator* ()
{
return *this;

View File

@@ -4,9 +4,8 @@
// 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.
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 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
@@ -20,9 +19,6 @@
#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>
@@ -42,39 +38,35 @@ namespace boost { namespace geometry
template <typename Geometry1, typename Geometry2, typename CalculationType>
struct select_calculation_type
{
typedef typename
boost::mpl::if_
typedef std::conditional_t
<
boost::is_void<CalculationType>,
std::is_void<CalculationType>::value,
typename select_coordinate_type
<
Geometry1,
Geometry2
>::type,
CalculationType
>::type type;
> type;
};
// alternative version supporting more than 2 Geometries
template <typename CalculationType,
typename Geometry1,
typename Geometry2 = void,
typename Geometry3 = void>
template
<
typename CalculationType,
typename ...Geometries
>
struct select_calculation_type_alt
{
typedef typename
boost::mpl::if_
typedef std::conditional_t
<
boost::is_void<CalculationType>,
std::is_void<CalculationType>::value,
typename select_coordinate_type
<
Geometry1,
Geometry2,
Geometry3
Geometries...
>::type,
CalculationType
>::type type;
> type;
};

View File

@@ -4,9 +4,8 @@
// 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.
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 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
@@ -30,38 +29,18 @@ namespace boost { namespace geometry
/*!
\brief Meta-function selecting the most precise coordinate type
of two geometries
of geometries
\ingroup utility
*/
template <typename T1, typename T2 = void, typename T3 = void>
template <typename ...Geometries>
struct select_coordinate_type
{
typedef typename select_most_precise
<
typename coordinate_type<T1>::type,
typename coordinate_type<T2>::type,
typename coordinate_type<T3>::type
typename coordinate_type<Geometries>::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

View File

@@ -4,9 +4,8 @@
// 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.
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 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
@@ -19,9 +18,8 @@
#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>
#include <type_traits>
namespace boost { namespace geometry
@@ -33,66 +31,40 @@ 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;
};
// 0 - void
// 1 - integral
// 2 - floating point
// 3 - non-fundamental
template <typename T>
struct type_priority
: std::conditional_t
<
std::is_void<T>::value,
std::integral_constant<int, 0>,
std::conditional_t
<
std::is_fundamental<T>::value,
std::conditional_t
<
std::is_floating_point<T>::value,
std::integral_constant<int, 2>,
std::integral_constant<int, 1>
>,
std::integral_constant<int, 3>
>
>
{};
// 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 T>
struct type_size
: std::integral_constant<std::size_t, sizeof(T)>
{};
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;
};
template <>
struct type_size<void>
: std::integral_constant<std::size_t, 0>
{};
}} // namespace detail::select_most_precise
@@ -100,10 +72,10 @@ struct select_floating_point<false, true, T1, T2>
/*!
\brief Meta-function to select, of two types, the most accurate type for
\brief Meta-function to select the most accurate type for
calculations
\ingroup utility
\details select_most_precise classes, compares two types on compile time.
\details select_most_precise classes, compares 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.
@@ -111,71 +83,65 @@ struct select_floating_point<false, true, T1, T2>
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>
template <typename ...Types>
struct select_most_precise
{
typedef void type;
};
template <typename T>
struct select_most_precise<T>
{
typedef T type;
};
template <typename T1, typename T2>
struct select_most_precise<T1, T2>
{
static const int priority1 = detail::select_most_precise::type_priority<T1>::value;
static const int priority2 = detail::select_most_precise::type_priority<T2>::value;
static const std::size_t size1 = detail::select_most_precise::type_size<T1>::value;
static const std::size_t size2 = detail::select_most_precise::type_size<T2>::value;
typedef std::conditional_t
<
(priority1 > priority2),
T1,
std::conditional_t
<
(priority2 > priority1),
T2,
std::conditional_t // priority1 == priority2
<
(priority1 == 0 || priority1 == 3), // both void or non-fundamental
T1,
std::conditional_t // both fundamental
<
(size2 > size1),
T2,
T1
>
>
>
> type;
};
template <typename T1, typename T2, typename ...Types>
struct select_most_precise<T1, T2, Types...>
{
typedef typename select_most_precise
<
typename select_most_precise<T1, T2>::type,
T3
typename select_most_precise<Types...>::type
>::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

View File

@@ -1,78 +0,0 @@
// Boost.Geometry
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// 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_SEQUENCE_ELEMENT
#define BOOST_GEOMETRY_UTIL_SELECT_SEQUENCE_ELEMENT
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
namespace util
{
template <typename Curr, typename Next>
struct pred_more_precise_coordinate_type
{
typedef typename geometry::coordinate_type<Curr>::type curr_coord_t;
typedef typename geometry::coordinate_type<Next>::type next_coord_t;
typedef typename boost::mpl::if_c
<
boost::is_same
<
curr_coord_t,
typename select_most_precise
<
curr_coord_t,
next_coord_t
>::type
>::value,
Curr,
Next
>::type type;
};
template
<
typename Seq,
template<typename, typename> class Pred = pred_more_precise_coordinate_type,
int I = 0,
int N = boost::mpl::size<Seq>::value
>
struct select_sequence_element
{
typedef typename boost::mpl::at<Seq, boost::mpl::int_<I> >::type curr_t;
typedef typename select_sequence_element<Seq, Pred, I+1, N>::type next_t;
typedef typename Pred<curr_t, next_t>::type type;
};
template <typename Seq, template<typename, typename> class Pred, int N>
struct select_sequence_element<Seq, Pred, N, N>
{
typedef typename boost::mpl::at<Seq, boost::mpl::int_<N-1> >::type type;
};
} // namespace util
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_SELECT_SEQUENCE_ELEMENT

View File

@@ -0,0 +1,299 @@
// Boost.Geometry
// Copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, 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_SEQUENCE_HPP
#define BOOST_GEOMETRY_UTIL_SEQUENCE_HPP
#include <utility>
#include <type_traits>
namespace boost { namespace geometry
{
namespace util
{
// An alternative would be to use std:tuple and std::pair
// but it would add dependency.
template <typename ...Ts>
struct type_sequence {};
// true if T is a sequence
template <typename T>
struct is_sequence : std::false_type {};
template <typename ...Ts>
struct is_sequence<type_sequence<Ts...>> : std::true_type {};
template <typename T, T ...Is>
struct is_sequence<std::integer_sequence<T, Is...>> : std::true_type {};
// number of elements in a sequence
template <typename Sequence>
struct sequence_size {};
template <typename ...Ts>
struct sequence_size<type_sequence<Ts...>>
: std::integral_constant<std::size_t, sizeof...(Ts)>
{};
template <typename T, T ...Is>
struct sequence_size<std::integer_sequence<T, Is...>>
: std::integral_constant<std::size_t, sizeof...(Is)>
{};
// element of a sequence
template <std::size_t I, typename Sequence>
struct sequence_element {};
template <std::size_t I, typename T, typename ...Ts>
struct sequence_element<I, type_sequence<T, Ts...>>
{
using type = typename sequence_element<I - 1, type_sequence<Ts...>>::type;
};
template <typename T, typename ...Ts>
struct sequence_element<0, type_sequence<T, Ts...>>
{
using type = T;
};
template <std::size_t I, typename T, T J, T ...Js>
struct sequence_element<I, std::integer_sequence<T, J, Js...>>
: std::integral_constant
<
T,
sequence_element<I - 1, std::integer_sequence<T, Js...>>::value
>
{};
template <typename T, T J, T ...Js>
struct sequence_element<0, std::integer_sequence<T, J, Js...>>
: std::integral_constant<T, J>
{};
template <typename ...Ts>
struct pack_front
{
static_assert(sizeof...(Ts) > 0, "Parameter pack can not be empty.");
};
template <typename T, typename ... Ts>
struct pack_front<T, Ts...>
{
typedef T type;
};
template <typename Sequence>
struct sequence_front
: sequence_element<0, Sequence>
{
static_assert(sequence_size<Sequence>::value > 0, "Sequence can not be empty.");
};
template <typename Sequence>
struct sequence_back
: sequence_element<sequence_size<Sequence>::value - 1, Sequence>
{
static_assert(sequence_size<Sequence>::value > 0, "Sequence can not be empty.");
};
template <typename Sequence>
struct sequence_empty
: std::integral_constant
<
bool,
sequence_size<Sequence>::value == 0
>
{};
// Defines type member for the first type in sequence that satisfies UnaryPred.
template
<
typename Sequence,
template <typename> class UnaryPred
>
struct sequence_find_if {};
template
<
typename T, typename ...Ts,
template <typename> class UnaryPred
>
struct sequence_find_if<type_sequence<T, Ts...>, UnaryPred>
: std::conditional
<
UnaryPred<T>::value,
T,
// TODO: prevent instantiation for the rest of the sequence if value is true
typename sequence_find_if<type_sequence<Ts...>, UnaryPred>::type
>
{};
template <template <typename> class UnaryPred>
struct sequence_find_if<type_sequence<>, UnaryPred>
{
// TODO: This is technically incorrect because void can be stored in a type_sequence
using type = void;
};
// sequence_merge<type_sequence<A, B>, type_sequence<C, D>>::type is
// type_sequence<A, B, C, D>
// sequence_merge<integer_sequence<A, B>, integer_sequence<C, D>>::type is
// integer_sequence<A, B, C, D>
template <typename ...Sequences>
struct sequence_merge;
template <typename S>
struct sequence_merge<S>
{
using type = S;
};
template <typename ...T1s, typename ...T2s>
struct sequence_merge<type_sequence<T1s...>, type_sequence<T2s...>>
{
using type = type_sequence<T1s..., T2s...>;
};
template <typename T, T ...I1s, T ...I2s>
struct sequence_merge<std::integer_sequence<T, I1s...>, std::integer_sequence<T, I2s...>>
{
using type = std::integer_sequence<T, I1s..., I2s...>;
};
template <typename S1, typename S2, typename ...Sequences>
struct sequence_merge<S1, S2, Sequences...>
{
using type = typename sequence_merge
<
typename sequence_merge<S1, S2>::type,
typename sequence_merge<Sequences...>::type
>::type;
};
// sequence_combine<type_sequence<A, B>, type_sequence<C, D>>::type is
// type_sequence<type_sequence<A, C>, type_sequence<A, D>,
// type_sequence<B, C>, type_sequence<B, D>>
template <typename Sequence1, typename Sequence2>
struct sequence_combine;
template <typename ...T1s, typename ...T2s>
struct sequence_combine<type_sequence<T1s...>, type_sequence<T2s...>>
{
template <typename T1>
using type_sequence_t = type_sequence<type_sequence<T1, T2s>...>;
using type = typename sequence_merge<type_sequence_t<T1s>...>::type;
};
// sequence_combine<integer_sequence<T, 1, 2>, integer_sequence<T, 3, 4>>::type is
// type_sequence<integer_sequence<T, 1, 3>, integer_sequence<T, 1, 4>,
// integer_sequence<T, 2, 3>, integer_sequence<T, 2, 4>>
template <typename T, T ...I1s, T ...I2s>
struct sequence_combine<std::integer_sequence<T, I1s...>, std::integer_sequence<T, I2s...>>
{
template <T I1>
using type_sequence_t = type_sequence<std::integer_sequence<T, I1, I2s>...>;
using type = typename sequence_merge<type_sequence_t<I1s>...>::type;
};
// Selects least element from a parameter pack based on
// LessPred<T1, T2>::value comparison, similar to std::min_element
template
<
template <typename, typename> class LessPred,
typename ...Ts
>
struct pack_min_element;
template
<
template <typename, typename> class LessPred,
typename T
>
struct pack_min_element<LessPred, T>
{
using type = T;
};
template
<
template <typename, typename> class LessPred,
typename T1, typename T2
>
struct pack_min_element<LessPred, T1, T2>
{
using type = std::conditional_t<LessPred<T1, T2>::value, T1, T2>;
};
template
<
template <typename, typename> class LessPred,
typename T1, typename T2, typename ...Ts
>
struct pack_min_element<LessPred, T1, T2, Ts...>
{
using type = typename pack_min_element
<
LessPred,
typename pack_min_element<LessPred, T1, T2>::type,
typename pack_min_element<LessPred, Ts...>::type
>::type;
};
// Selects least element from a sequence based on
// LessPred<T1, T2>::value comparison, similar to std::min_element
template
<
typename Sequence,
template <typename, typename> class LessPred
>
struct sequence_min_element;
template
<
typename ...Ts,
template <typename, typename> class LessPred
>
struct sequence_min_element<type_sequence<Ts...>, LessPred>
{
using type = typename pack_min_element<LessPred, Ts...>::type;
};
// TODO: Since there are two kinds of parameter packs and sequences there probably should be two
// versions of sequence_find_if as well as parameter_pack_min_element and sequence_min_element.
// Currently these utilities support only types.
} // namespace util
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_SEQUENCE_HPP

View File

@@ -1,9 +1,15 @@
// Boost.Geometry
// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program.
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 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)
@@ -55,11 +61,12 @@ namespace boost { namespace geometry { namespace series_expansion {
s/case\sCT(/case /g; s/):/:/g; s/epsCT(2)/eps2/g;'
*/
template <size_t SeriesOrder, typename CT>
inline CT evaluate_A1(CT eps)
inline CT evaluate_A1(CT const& eps)
{
CT eps2 = math::sqr(eps);
CT const eps2 = math::sqr(eps);
CT t;
switch (SeriesOrder/2) {
switch (SeriesOrder/2)
{
case 0:
t = CT(0);
break;
@@ -72,7 +79,7 @@ namespace boost { namespace geometry { namespace series_expansion {
case 3:
t = eps2*(eps2*(eps2+CT(4))+CT(64))/CT(256);
break;
case 4:
default:
t = eps2*(eps2*(eps2*(CT(25)*eps2+CT(64))+CT(256))+CT(4096))/CT(16384);
break;
}
@@ -104,7 +111,8 @@ namespace boost { namespace geometry { namespace series_expansion {
{
CT const eps2 = math::sqr(eps);
CT t;
switch (SeriesOrder/2) {
switch (SeriesOrder/2)
{
case 0:
t = CT(0);
break;
@@ -147,7 +155,8 @@ namespace boost { namespace geometry { namespace series_expansion {
template <typename Coeffs, typename CT>
inline void evaluate_coeffs_A3(Coeffs &c, CT const& n)
{
switch (int(Coeffs::static_size)) {
switch (int(Coeffs::static_size))
{
case 0:
break;
case 1:
@@ -216,9 +225,10 @@ namespace boost { namespace geometry { namespace series_expansion {
template <typename Coeffs, typename CT>
inline void evaluate_coeffs_C1(Coeffs &c, CT const& eps)
{
CT eps2 = math::sqr(eps);
CT const eps2 = math::sqr(eps);
CT d = eps;
switch (int(Coeffs::static_size) - 1) {
switch (int(Coeffs::static_size) - 1)
{
case 0:
break;
case 1:
@@ -317,7 +327,8 @@ namespace boost { namespace geometry { namespace series_expansion {
{
CT const eps2 = math::sqr(eps);
CT d = eps;
switch (int(Coeffs::static_size) - 1) {
switch (int(Coeffs::static_size) - 1)
{
case 0:
break;
case 1:
@@ -416,7 +427,8 @@ namespace boost { namespace geometry { namespace series_expansion {
{
CT const eps2 = math::sqr(eps);
CT d = eps;
switch (int(Coeffs::static_size) - 1) {
switch (int(Coeffs::static_size) - 1)
{
case 0:
break;
case 1:
@@ -512,12 +524,11 @@ namespace boost { namespace geometry { namespace series_expansion {
*/
template <size_t SeriesOrder, typename Coeffs, typename CT>
inline void evaluate_coeffs_C3x(Coeffs &c, CT const& n) {
size_t const coeff_size = Coeffs::static_size;
size_t const expected_size = (SeriesOrder * (SeriesOrder - 1)) / 2;
BOOST_GEOMETRY_ASSERT((coeff_size == expected_size));
BOOST_GEOMETRY_ASSERT((Coeffs::static_size == (SeriesOrder * (SeriesOrder - 1)) / 2));
const CT n2 = math::sqr(n);
switch (SeriesOrder) {
CT const n2 = math::sqr(n);
switch (SeriesOrder)
{
case 0:
break;
case 1:
@@ -633,16 +644,16 @@ namespace boost { namespace geometry { namespace series_expansion {
inline void evaluate_coeffs_C3(Coeffs1 &coeffs1, Coeffs2 &coeffs2, CT const& eps)
{
CT mult = 1;
int offset = 0;
size_t offset = 0;
// l is the index of C3[l].
for (size_t l = 1; l < Coeffs1::static_size; ++l)
// i is the index of C3[i].
for (size_t i = 1; i < Coeffs1::static_size; ++i)
{
// Order of polynomial in eps.
int m = Coeffs1::static_size - l;
size_t m = Coeffs1::static_size - i;
mult *= eps;
coeffs1[l] = mult * math::horner_evaluate(eps, coeffs2.begin() + offset,
coeffs1[i] = mult * math::horner_evaluate(eps, coeffs2.begin() + offset,
coeffs2.begin() + offset + m);
offset += m;

View File

@@ -4,10 +4,11 @@
// 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.
// This file was modified by Oracle on 2015-2020.
// Modifications copyright (c) 2015-2020, 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.
@@ -20,6 +21,12 @@
#define BOOST_GEOMETRY_UTIL_TRANSFORM_VARIANT_HPP
#include <boost/config/pragma_message.hpp>
#if !defined(BOOST_ALLOW_DEPRECATED_HEADERS)
BOOST_PRAGMA_MESSAGE("This header is deprecated.")
#endif
#include <boost/mpl/transform.hpp>
#include <boost/variant/variant_fwd.hpp>

View File

@@ -0,0 +1,389 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 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_TUPLES_HPP
#define BOOST_GEOMETRY_UTIL_TUPLES_HPP
#include <tuple>
#include <type_traits>
#include <utility>
#include <boost/geometry/core/config.hpp>
#include <boost/tuple/tuple.hpp>
namespace boost { namespace geometry { namespace tuples
{
template <typename T>
struct is_tuple
: std::integral_constant<bool, false>
{};
template <typename ...Ts>
struct is_tuple<std::tuple<Ts...>>
: std::integral_constant<bool, true>
{};
template <typename F, typename S>
struct is_tuple<std::pair<F, S>>
: std::integral_constant<bool, true>
{};
template <typename ...Ts>
struct is_tuple<boost::tuples::tuple<Ts...>>
: std::integral_constant<bool, true>
{};
template <typename HT, typename TT>
struct is_tuple<boost::tuples::cons<HT, TT>>
: std::integral_constant<bool, true>
{};
template <std::size_t I, typename Tuple>
struct element;
template <std::size_t I, typename ...Ts>
struct element<I, std::tuple<Ts...>>
: std::tuple_element<I, std::tuple<Ts...>>
{};
template <std::size_t I, typename HT, typename TT>
struct element<I, std::pair<HT, TT>>
: std::tuple_element<I, std::pair<HT, TT>>
{};
template <std::size_t I, typename ...Ts>
struct element<I, boost::tuples::tuple<Ts...>>
{
typedef typename boost::tuples::element
<
I, boost::tuples::tuple<Ts...>
>::type type;
};
template <std::size_t I, typename HT, typename TT>
struct element<I, boost::tuples::cons<HT, TT>>
{
typedef typename boost::tuples::element
<
I, boost::tuples::cons<HT, TT>
>::type type;
};
template <typename Tuple>
struct size;
template <typename ...Ts>
struct size<std::tuple<Ts...>>
: std::tuple_size<std::tuple<Ts...>>
{};
template <typename HT, typename TT>
struct size<std::pair<HT, TT>>
: std::tuple_size<std::pair<HT, TT>>
{};
template <typename ...Ts>
struct size<boost::tuples::tuple<Ts...>>
: std::integral_constant
<
std::size_t,
boost::tuples::length<boost::tuples::tuple<Ts...>>::value
>
{};
template <typename HT, typename TT>
struct size<boost::tuples::cons<HT, TT>>
: std::integral_constant
<
std::size_t,
boost::tuples::length<boost::tuples::cons<HT, TT>>::value
>
{};
template <std::size_t I, typename ...Ts>
constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type&
get(std::tuple<Ts...> & t)
{
return std::get<I>(t);
}
template <std::size_t I, typename ...Ts>
constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type const&
get(std::tuple<Ts...> const& t)
{
return std::get<I>(t);
}
template <std::size_t I, typename HT, typename TT>
constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type&
get(std::pair<HT, TT> & t)
{
return std::get<I>(t);
}
template <std::size_t I, typename HT, typename TT>
constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type const&
get(std::pair<HT, TT> const& t)
{
return std::get<I>(t);
}
template <std::size_t I, typename ...Ts>
inline typename boost::tuples::access_traits
<
typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
>::non_const_type
get(boost::tuples::tuple<Ts...> & t)
{
return boost::tuples::get<I>(t);
}
template <std::size_t I, typename ...Ts>
inline typename boost::tuples::access_traits
<
typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
>::const_type
get(boost::tuples::tuple<Ts...> const& t)
{
return boost::tuples::get<I>(t);
}
template <std::size_t I, typename HT, typename TT>
inline typename boost::tuples::access_traits
<
typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
>::non_const_type
get(boost::tuples::cons<HT, TT> & tup)
{
return boost::tuples::get<I>(tup);
}
template <std::size_t I, typename HT, typename TT>
inline typename boost::tuples::access_traits
<
typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
>::const_type
get(boost::tuples::cons<HT, TT> const& tup)
{
return boost::tuples::get<I>(tup);
}
// find_index_if
// Searches for the index of an element for which UnaryPredicate returns true
// If such element is not found the result is N
template
<
typename Tuple,
template <typename> class UnaryPred,
std::size_t I = 0,
std::size_t N = size<Tuple>::value
>
struct find_index_if
: std::conditional_t
<
UnaryPred<typename element<I, Tuple>::type>::value,
std::integral_constant<std::size_t, I>,
typename find_index_if<Tuple, UnaryPred, I+1, N>::type
>
{};
template
<
typename Tuple,
template <typename> class UnaryPred,
std::size_t N
>
struct find_index_if<Tuple, UnaryPred, N, N>
: std::integral_constant<std::size_t, N>
{};
// find_if
// Searches for an element for which UnaryPredicate returns true
// If such element is not found the result is detail::null_type
namespace detail
{
struct null_type {};
} // detail
template
<
typename Tuple,
template <typename> class UnaryPred,
std::size_t I = 0,
std::size_t N = size<Tuple>::value
>
struct find_if
: std::conditional_t
<
UnaryPred<typename element<I, Tuple>::type>::value,
element<I, Tuple>,
find_if<Tuple, UnaryPred, I+1, N>
>
{};
template
<
typename Tuple,
template <typename> class UnaryPred,
std::size_t N
>
struct find_if<Tuple, UnaryPred, N, N>
{
typedef detail::null_type type;
};
// is_found
// Returns true if a type T (the result of find_if) was found.
template <typename T>
struct is_found
: std::integral_constant
<
bool,
! std::is_same<T, detail::null_type>::value
>
{};
// is_not_found
// Returns true if a type T (the result of find_if) was not found.
template <typename T>
struct is_not_found
: std::is_same<T, detail::null_type>
{};
// exists_if
// Returns true if search for element meeting UnaryPred can be found.
template <typename Tuple, template <typename> class UnaryPred>
struct exists_if
: is_found<typename find_if<Tuple, UnaryPred>::type>
{};
// push_back
// A utility used to create a type/object of a Tuple containing
// all types/objects stored in another Tuple plus additional one.
template <typename Tuple,
typename T,
std::size_t I = 0,
std::size_t N = size<Tuple>::value>
struct push_back_bt
{
typedef
boost::tuples::cons<
typename element<I, Tuple>::type,
typename push_back_bt<Tuple, T, I+1, N>::type
> type;
static type apply(Tuple const& tup, T const& t)
{
return
type(
geometry::tuples::get<I>(tup),
push_back_bt<Tuple, T, I+1, N>::apply(tup, t)
);
}
};
template <typename Tuple, typename T, std::size_t N>
struct push_back_bt<Tuple, T, N, N>
{
typedef boost::tuples::cons<T, boost::tuples::null_type> type;
static type apply(Tuple const&, T const& t)
{
return type(t, boost::tuples::null_type());
}
};
template <typename Tuple, typename T>
struct push_back
: push_back_bt<Tuple, T>
{};
template <typename F, typename S, typename T>
struct push_back<std::pair<F, S>, T>
{
typedef std::tuple<F, S, T> type;
static type apply(std::pair<F, S> const& p, T const& t)
{
return type(p.first, p.second, t);
}
static type apply(std::pair<F, S> && p, T const& t)
{
return type(std::move(p.first), std::move(p.second), t);
}
static type apply(std::pair<F, S> && p, T && t)
{
return type(std::move(p.first), std::move(p.second), std::move(t));
}
};
template <typename Is, typename Tuple, typename T>
struct push_back_st;
template <std::size_t ...Is, typename ...Ts, typename T>
struct push_back_st<std::index_sequence<Is...>, std::tuple<Ts...>, T>
{
typedef std::tuple<Ts..., T> type;
static type apply(std::tuple<Ts...> const& tup, T const& t)
{
return type(std::get<Is>(tup)..., t);
}
static type apply(std::tuple<Ts...> && tup, T const& t)
{
return type(std::move(std::get<Is>(tup))..., t);
}
static type apply(std::tuple<Ts...> && tup, T && t)
{
return type(std::move(std::get<Is>(tup))..., std::move(t));
}
};
template <typename ...Ts, typename T>
struct push_back<std::tuple<Ts...>, T>
: push_back_st
<
std::make_index_sequence<sizeof...(Ts)>,
std::tuple<Ts...>,
T
>
{};
}}} // namespace boost::geometry::tuples
#endif // BOOST_GEOMETRY_UTIL_TUPLES_HPP

View File

@@ -0,0 +1,315 @@
// Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
// 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_TYPE_TRAITS_HPP
#define BOOST_GEOMETRY_UTIL_TYPE_TRAITS_HPP
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/type_traits_std.hpp>
namespace boost { namespace geometry
{
namespace util
{
template <typename T>
struct is_geometry
: bool_constant<! std::is_void<typename tag<T>::type>::value>
{};
template <typename T>
struct is_not_geometry
: std::is_void<typename tag<T>::type>
{};
template <typename T>
struct is_point
: std::is_same<point_tag, typename tag<T>::type>
{};
template <typename T>
struct is_multi_point
: std::is_same<multi_point_tag, typename tag<T>::type>
{};
template <typename T>
struct is_pointlike
: std::is_base_of<pointlike_tag, typename tag<T>::type>
{};
template <typename T>
struct is_segment
: std::is_same<segment_tag, typename tag<T>::type>
{};
template <typename T>
struct is_linestring
: std::is_same<linestring_tag, typename tag<T>::type>
{};
template <typename T>
struct is_multi_linestring
: std::is_same<multi_linestring_tag, typename tag<T>::type>
{};
template <typename T>
struct is_polylinear
: std::is_base_of<polylinear_tag, typename tag<T>::type>
{};
template <typename T>
struct is_linear
: std::is_base_of<linear_tag, typename tag<T>::type>
{};
template <typename T>
struct is_box
: std::is_same<box_tag, typename tag<T>::type>
{};
template <typename T>
struct is_ring
: std::is_same<ring_tag, typename tag<T>::type>
{};
template <typename T>
struct is_polygon
: std::is_same<polygon_tag, typename tag<T>::type>
{};
template <typename T>
struct is_multi_polygon
: std::is_same<multi_polygon_tag, typename tag<T>::type>
{};
template <typename T>
struct is_polygonal
: std::is_base_of<polygonal_tag, typename tag<T>::type>
{};
template <typename T>
struct is_areal
: std::is_base_of<areal_tag, typename tag<T>::type>
{};
template <typename T>
struct is_segmental
: bool_constant<is_linear<T>::value || is_polygonal<T>::value>
{};
template <typename T>
struct is_polysegmental
: bool_constant<is_polylinear<T>::value || is_polygonal<T>::value>
{};
template <typename T>
struct is_multi
: std::is_base_of<multi_tag, typename tag<T>::type>
{};
template <typename T>
struct is_multi_element
: bool_constant<is_point<T>::value || is_linestring<T>::value || is_polygon<T>::value>
{};
template <typename T>
struct is_single
: std::is_base_of<single_tag, typename tag<T>::type>
{};
template <typename T>
struct is_geometry_collection
: std::is_same<geometry_collection_tag, typename tag<T>::type>
{};
template <typename T>
struct is_dynamic_geometry
: std::is_same<dynamic_geometry_tag, typename tag<T>::type>
{};
template <typename Geometry, typename T = void>
struct enable_if_point
: std::enable_if<is_point<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_point_t = typename enable_if_point<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_multi_point
: std::enable_if<is_multi_point<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_multi_point_t = typename enable_if_multi_point<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_pointlike
: std::enable_if<is_pointlike<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_pointlike_t = typename enable_if_pointlike<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_segment
: std::enable_if<is_segment<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_segment_t = typename enable_if_segment<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_linestring
: std::enable_if<is_linestring<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_linestring_t = typename enable_if_linestring<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_multi_linestring
: std::enable_if<is_multi_linestring<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_multi_linestring_t = typename enable_if_multi_linestring<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_polylinear
: std::enable_if<is_polylinear<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_polylinear_t = typename enable_if_polylinear<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_linear
: std::enable_if<is_linear<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_linear_t = typename enable_if_linear<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_box
: std::enable_if<is_box<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_box_t = typename enable_if_box<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_ring
: std::enable_if<is_ring<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_ring_t = typename enable_if_ring<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_polygon
: std::enable_if<is_polygon<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_polygon_t = typename enable_if_polygon<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_multi_polygon
: std::enable_if<is_multi_polygon<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_multi_polygon_t = typename enable_if_multi_polygon<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_polygonal
: std::enable_if<is_polygonal<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_polygonal_t = typename enable_if_polygonal<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_areal
: std::enable_if<is_areal<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_areal_t = typename enable_if_areal<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_polysegmental
: std::enable_if<is_polysegmental<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_polysegmental_t = typename enable_if_polysegmental<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_dynamic_geometry
: std::enable_if<is_dynamic_geometry<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_dynamic_geometry_t = typename enable_if_dynamic_geometry<Geometry, T>::type;
template <typename Geometry, typename T = void>
struct enable_if_geometry_collection
: std::enable_if<is_geometry_collection<Geometry>::value, T>
{};
template <typename Geometry, typename T = void>
using enable_if_geometry_collection_t = typename enable_if_geometry_collection<Geometry, T>::type;
} // namespace util
// Deprecated utilities, defined for backward compatibility but might be
// removed in the future.
/*!
\brief Meta-function defining "true" for areal types (box, (multi)polygon, ring),
\note Used for tag dispatching and meta-function finetuning
\note Also a "ring" has areal properties within Boost.Geometry
\ingroup core
*/
using util::is_areal;
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_DETAIL_HPP

View File

@@ -0,0 +1,220 @@
// Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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_TYPE_TRAITS_STD_HPP
#define BOOST_GEOMETRY_UTIL_TYPE_TRAITS_STD_HPP
#include <cstddef>
#include <type_traits>
namespace boost { namespace geometry
{
namespace util
{
// C++17
template <bool B>
using bool_constant = std::integral_constant<bool, B>;
// non-standard
template <int I>
using int_constant = std::integral_constant<int, I>;
// non-standard
template <std::size_t I>
using index_constant = std::integral_constant<std::size_t, I>;
// non-standard
template <std::size_t S>
using size_constant = std::integral_constant<std::size_t, S>;
// C++17
template <typename ...>
struct conjunction
: std::true_type
{};
template<typename Trait>
struct conjunction<Trait>
: Trait
{};
template <typename Trait, typename ...Traits>
struct conjunction<Trait, Traits...>
: std::conditional_t<Trait::value, conjunction<Traits...>, Trait>
{};
// C++17
template <typename ...>
struct disjunction
: std::false_type
{};
template <typename Trait>
struct disjunction<Trait>
: Trait
{};
template <typename Trait, typename ...Traits>
struct disjunction<Trait, Traits...>
: std::conditional_t<Trait::value, Trait, disjunction<Traits...>>
{};
// C++17
template <typename Trait>
struct negation
: bool_constant<!Trait::value>
{};
// non-standard
/*
template <typename ...Traits>
using and_ = conjunction<Traits...>;
template <typename ...Traits>
using or_ = disjunction<Traits...>;
template <typename Trait>
using not_ = negation<Trait>;
*/
// C++20
template <typename T>
struct remove_cvref
{
using type = std::remove_cv_t<std::remove_reference_t<T>>;
};
template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;
// non-standard
template <typename T>
struct remove_cref
{
using type = std::remove_const_t<std::remove_reference_t<T>>;
};
template <typename T>
using remove_cref_t = typename remove_cref<T>::type;
// non-standard
template <typename T>
struct remove_cptrref
{
using type = std::remove_const_t
<
std::remove_pointer_t<std::remove_reference_t<T>>
>;
};
template <typename T>
using remove_cptrref_t = typename remove_cptrref<T>::type;
// non-standard
template <typename From, typename To>
struct transcribe_const
{
using type = std::conditional_t
<
std::is_const<std::remove_reference_t<From>>::value,
std::add_const_t<To>,
To
>;
};
template <typename From, typename To>
using transcribe_const_t = typename transcribe_const<From, To>::type;
// non-standard
template <typename From, typename To>
struct transcribe_reference
{
using type = std::remove_reference_t<To>;
};
template <typename From, typename To>
struct transcribe_reference<From &, To>
{
using type = std::remove_reference_t<To> &;
};
template <typename From, typename To>
struct transcribe_reference<From &&, To>
{
using type = std::remove_reference_t<To> &&;
};
template <typename From, typename To>
using transcribe_reference_t = typename transcribe_reference<From, To>::type;
// non-standard
template <typename From, typename To>
struct transcribe_cref
{
using type = transcribe_reference_t<From, transcribe_const_t<From, To>>;
};
template <typename From, typename To>
using transcribe_cref_t = typename transcribe_cref<From, To>::type;
} // namespace util
// Deprecated utilities, defined for backward compatibility but might be
// removed in the future.
/*!
\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 std::conditional_t
<
IsConst,
Type const,
Type
> type;
};
namespace util
{
template <typename T>
using bare_type = remove_cptrref<T>;
} // namespace util
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_TYPE_TRAITS_STD_HPP