mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-09 15:14:02 +00:00
[distance] Use transform_variant
Remove dependency to is_implemented. Update transform_variant to support MPL sequence input.
This commit is contained in:
parent
595f6fe457
commit
09a8ba53a7
@ -4,6 +4,7 @@
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
@ -43,7 +44,11 @@
|
||||
#include <boost/geometry/util/compress_variant.hpp>
|
||||
#include <boost/geometry/util/transform_variant.hpp>
|
||||
#include <boost/geometry/util/combine_if.hpp>
|
||||
#include <boost/geometry/util/is_implemented.hpp>
|
||||
//#include <boost/geometry/util/is_implemented.hpp>
|
||||
|
||||
#include <boost/mpl/always.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -166,30 +171,28 @@ struct distance
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy>
|
||||
struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy>
|
||||
{
|
||||
// A set of of all variant type combinations that are compatible and implemented
|
||||
typedef typename util::combine_if
|
||||
<
|
||||
typename mpl::vector1<Geometry1>,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
util::is_compatible<mpl::_1, mpl::_2>
|
||||
>::type possible_input_types;
|
||||
// A set of all variant type combinations that are compatible and implemented
|
||||
typedef typename util::combine_if<
|
||||
typename mpl::vector1<Geometry1>,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
// Here we want should remove most of the combinations that are not valid
|
||||
// mostly to limit the size of the resulting MPL set.
|
||||
// But is_implementedn is not ready for prime time
|
||||
//
|
||||
// util::is_implemented2<mpl::_1, mpl::_2, dispatch::distance<mpl::_1, mpl::_2> >
|
||||
mpl::always<mpl::true_>
|
||||
>::type possible_input_types;
|
||||
|
||||
// All possible results for these combinations
|
||||
typedef typename mpl::transform<
|
||||
possible_input_types,
|
||||
resolve_strategy::result_of::distance
|
||||
<
|
||||
// The (possibly variant) result type resulting from these combinations
|
||||
typedef typename compress_variant<
|
||||
typename transform_variant<
|
||||
possible_input_types,
|
||||
resolve_strategy::result_of::distance<
|
||||
point_type<mpl::first<mpl::_> >,
|
||||
point_type<mpl::second<mpl::_> >,
|
||||
Strategy
|
||||
>,
|
||||
mpl::back_inserter<mpl::vector0<> >
|
||||
>::type possible_result_types;
|
||||
|
||||
// The (possibly variant) result type
|
||||
typedef typename compress_variant<
|
||||
typename make_variant_over<
|
||||
possible_result_types
|
||||
mpl::back_inserter<mpl::vector0<> >
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
@ -205,30 +208,29 @@ struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2, Strategy>
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy>
|
||||
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy>
|
||||
{
|
||||
// A set of of all variant type combinations that are compatible and implemented
|
||||
// A set of all variant type combinations that are compatible and implemented
|
||||
typedef typename util::combine_if
|
||||
<
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
util::is_compatible<mpl::_1, mpl::_2>
|
||||
// Here we want to try to remove most of the combinations that are not valid
|
||||
// mostly to limit the size of the resulting MPL vector.
|
||||
// But is_implementedn is not ready for prime time
|
||||
//
|
||||
// util::is_implemented2<mpl::_1, mpl::_2, dispatch::distance<mpl::_1, mpl::_2> >
|
||||
mpl::always<mpl::true_>
|
||||
>::type possible_input_types;
|
||||
|
||||
// All possible results for these combinations
|
||||
typedef typename mpl::transform<
|
||||
possible_input_types,
|
||||
resolve_strategy::result_of::distance
|
||||
<
|
||||
// The (possibly variant) result type resulting from these combinations
|
||||
typedef typename compress_variant<
|
||||
typename transform_variant<
|
||||
possible_input_types,
|
||||
resolve_strategy::result_of::distance<
|
||||
point_type<mpl::first<mpl::_> >,
|
||||
point_type<mpl::second<mpl::_> >,
|
||||
Strategy
|
||||
>,
|
||||
mpl::back_inserter<mpl::vector0<> >
|
||||
>::type possible_result_types;
|
||||
|
||||
// The (possibly variant) result type
|
||||
typedef typename compress_variant<
|
||||
typename make_variant_over<
|
||||
possible_result_types
|
||||
mpl::back_inserter<mpl::vector0<> >
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
@ -23,4 +23,4 @@
|
||||
#include <boost/geometry/algorithms/detail/distance/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/implementation.hpp>
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
|
||||
|
@ -15,18 +15,63 @@
|
||||
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Algorithm>
|
||||
struct is_implemented1
|
||||
: mpl::not_
|
||||
<
|
||||
typename is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
//typename mpl::apply1<Algorithm, Geometry>::type
|
||||
Algorithm
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Algorithm>
|
||||
struct is_implemented2
|
||||
: mpl::not_
|
||||
<
|
||||
typename is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
//typename mpl::apply2<Algorithm, Geometry1, Geometry2>::type
|
||||
Algorithm
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function to check whether two geometry types
|
||||
have the same dimensions and coordinate systems
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct is_same_dimension_and_coordinate_system
|
||||
struct is_compatible2
|
||||
: mpl::and_
|
||||
<
|
||||
typename is_same
|
||||
@ -43,25 +88,33 @@ struct is_same_dimension_and_coordinate_system
|
||||
{};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct is_implemented
|
||||
: mpl::not_
|
||||
/*!
|
||||
\brief Meta-function to check whether an Unary Algorithm
|
||||
is implemented for the given geometry types
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Geometry, typename Algorithm>
|
||||
struct is_implemented1
|
||||
: mpl::and_
|
||||
<
|
||||
typename is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
geometry::dispatch::distance<Geometry1, Geometry2>
|
||||
>::type
|
||||
typename detail::is_implemented1<Geometry, Algorithm>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct is_compatible
|
||||
/*!
|
||||
\brief Meta-function to check whether an Binary Algorithm
|
||||
is implemented for the given geometry types
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Algorithm>
|
||||
struct is_implemented2
|
||||
: mpl::and_
|
||||
<
|
||||
typename is_same_dimension_and_coordinate_system<Geometry1, Geometry2>::type,
|
||||
typename is_implemented<Geometry1, Geometry2>::type
|
||||
// is_compatible is necessary because of some MPL_ASSERT
|
||||
// shortcuting the not_implemented class when dimension / coordinate system differs
|
||||
typename is_compatible2<Geometry1, Geometry2>::type,
|
||||
typename detail::is_implemented2<Geometry1, Geometry2, Algorithm>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
@ -23,10 +23,36 @@ namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a Sequence type, an MPL lambda
|
||||
expression and an optional Inserter and returns a variant type over
|
||||
the same types as the initial variant type, each transformed using
|
||||
the lambda expression.
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef mpl::vector<int, float, long> types;
|
||||
typedef transform_variant<types, add_pointer<_> > transformed;
|
||||
typedef variant<int*, float*, long*> result;
|
||||
BOOST_MPL_ASSERT(( equal<result, transformed> ));
|
||||
\endcode
|
||||
*/
|
||||
template <typename Sequence, typename Op, typename In = boost::mpl::na>
|
||||
struct transform_variant:
|
||||
make_variant_over<
|
||||
typename mpl::transform<
|
||||
Sequence,
|
||||
Op,
|
||||
In
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a boost::variant type and an MPL lambda
|
||||
expression and returns a variant type over the same types as the
|
||||
initial variant type, each trasnformed using the lambda expression.
|
||||
initial variant type, each transformed using the lambda expression.
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
@ -36,12 +62,11 @@ namespace boost { namespace geometry
|
||||
BOOST_MPL_ASSERT(( equal<result, transformed> ));
|
||||
\endcode
|
||||
*/
|
||||
|
||||
template <typename Variant, typename Op>
|
||||
struct transform_variant:
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Op>
|
||||
struct transform_variant<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Op, boost::mpl::na> :
|
||||
make_variant_over<
|
||||
typename mpl::transform<
|
||||
typename Variant::types,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
Op
|
||||
>::type
|
||||
>
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
|
||||
#include <boost/geometry/multi/io/wkt/read.hpp>
|
||||
|
||||
// includes for variant
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
||||
BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
|
||||
@ -363,7 +362,6 @@ void test_all()
|
||||
test_geometry<P, test::wrapped_boost_array<P, 2> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
|
||||
|
||||
test_distance_linear<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
|
||||
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
@ -439,7 +437,8 @@ void test_variant()
|
||||
{
|
||||
typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
|
||||
typedef bg::model::segment<point_type> segment_type;
|
||||
typedef boost::variant<point_type, segment_type> variant_type;
|
||||
typedef bg::model::box<point_type> box_type;
|
||||
typedef boost::variant<point_type, segment_type, box_type> variant_type;
|
||||
|
||||
point_type point;
|
||||
std::string const point_li = "POINT(1 3)";
|
||||
@ -451,9 +450,6 @@ void test_variant()
|
||||
|
||||
variant_type v1, v2;
|
||||
|
||||
v1 = point;
|
||||
v2 = point;
|
||||
|
||||
BOOST_MPL_ASSERT((
|
||||
boost::is_same
|
||||
<
|
||||
@ -462,6 +458,9 @@ void test_variant()
|
||||
>
|
||||
));
|
||||
|
||||
// Default strategy
|
||||
v1 = point;
|
||||
v2 = point;
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, point), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, point), bg::distance(point, point), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, point), 0.0001);
|
||||
@ -470,6 +469,14 @@ void test_variant()
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, seg), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, seg), bg::distance(point, seg), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, seg), 0.0001);
|
||||
|
||||
// User defined strategy
|
||||
v1 = point;
|
||||
v2 = point;
|
||||
bg::strategy::distance::haversine<double> s;
|
||||
//BOOST_CHECK_CLOSE(bg::distance(v1, v2, s), bg::distance(point, point, s), 0.0001);
|
||||
//BOOST_CHECK_CLOSE(bg::distance(v1, point, s), bg::distance(point, point, s), 0.0001);
|
||||
//BOOST_CHECK_CLOSE(bg::distance(point, v2, s), bg::distance(point, point, s), 0.0001);
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
|
88
test/util/is_implemented.cpp
Normal file
88
test/util/is_implemented.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/strategies/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/util/is_implemented.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace services
|
||||
{
|
||||
|
||||
|
||||
template <typename Strategy> struct tag
|
||||
{
|
||||
|
||||
typedef not_implemented type;
|
||||
|
||||
};
|
||||
|
||||
}} // namespace strategy::services
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Strategy,
|
||||
typename Tag1 = typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename Tag2 = typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
typename StrategyTag = typename strategy::services::tag<Strategy>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct algorithm_archetype
|
||||
: not_implemented<>
|
||||
{};
|
||||
|
||||
|
||||
struct strategy_archetype
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static void apply(Geometry1, Geometry2) {}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
typedef bg::model::d2::point_xy<double> point_type;
|
||||
|
||||
BOOST_MPL_ASSERT((
|
||||
boost::is_same<
|
||||
bg::util::is_implemented2
|
||||
<
|
||||
point_type, point_type,
|
||||
bg::algorithm_archetype<point_type, point_type, bg::strategy_archetype>
|
||||
>::type,
|
||||
boost::mpl::false_
|
||||
>
|
||||
));
|
||||
|
||||
return 0;
|
||||
}
|
@ -39,12 +39,30 @@ void check(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>)
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
typedef typename boost::geometry::transform_variant<
|
||||
// Transform Variant to Variant
|
||||
typedef boost::geometry::transform_variant<
|
||||
boost::variant<int, float, long>,
|
||||
boost::add_pointer<_>
|
||||
>::type transformed;
|
||||
>::type transformed1;
|
||||
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed());
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed1());
|
||||
|
||||
// Transform Sequence to Variant (without inserter)
|
||||
typedef boost::geometry::transform_variant<
|
||||
boost::mpl::vector<int, float, long>,
|
||||
boost::add_pointer<_>
|
||||
>::type transformed2;
|
||||
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed2());
|
||||
|
||||
// Transform Sequence to Variant (with inserter)
|
||||
typedef boost::geometry::transform_variant<
|
||||
boost::mpl::vector<int, float, long>,
|
||||
boost::add_pointer<_>,
|
||||
boost::mpl::back_inserter<boost::mpl::vector0<> >
|
||||
>::type transformed3;
|
||||
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed3());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user