From 122a6344ffd77b41e1994aebd2e7aecb4671c333 Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Mon, 12 May 2014 17:12:19 +0200 Subject: [PATCH 01/10] [distance] Add variant support Add variant dispatch layer to the distance algorithm --- .../boost/geometry/algorithms/distance.hpp | 277 +++++++++++++++++- 1 file changed, 266 insertions(+), 11 deletions(-) diff --git a/include/boost/geometry/algorithms/distance.hpp b/include/boost/geometry/algorithms/distance.hpp index 953be2361..685d1f580 100644 --- a/include/boost/geometry/algorithms/distance.hpp +++ b/include/boost/geometry/algorithms/distance.hpp @@ -22,7 +22,18 @@ #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -497,6 +508,252 @@ struct distance } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH + +namespace resolve_variant { + + +template +struct distance +{ + template + struct result_type + { + typedef typename strategy::distance::services::return_type< + Strategy, + typename point_type::type, + typename point_type::type + >::type type; + }; + + template + static inline typename result_type::type + apply( + const Geometry1& geometry1, + const Geometry2& geometry2, + Strategy const& strategy) + { + return dispatch::distance + < + Geometry1, + Geometry2, + Strategy + >::apply(geometry1, geometry2, strategy); + } +}; + + +template +struct distance, Geometry2> +{ + template + struct result_type + { + typedef typename mpl::fold< + typename mpl::transform< + typename variant::types, + typename strategy::distance::services::return_type< + Strategy, + typename mpl::lambda >::type, + typename point_type::type + >::type + >::type, + mpl::set0<>, + mpl::insert + >::type possible_result_types; + + typedef typename mpl::if_< + mpl::greater< + mpl::size, + mpl::int_<1> + >, + typename make_variant_over::type, + typename mpl::front::type + >::type type; + }; + + template + struct visitor: static_visitor< + typename result_type >::type + > + { + Geometry2 const& m_geometry2; + Strategy const& m_strategy; + + visitor(Geometry2 const& geometry2) + : m_geometry2(geometry2), + m_strategy(strategy) + {} + + template + result_type operator()(Geometry1 const& geometry1) const + { + return dispatch::distance + < + Geometry1, + Geometry2, + Strategy + >::apply(geometry1, geometry2, strategy); + } + }; + + template + static inline typename result_type >::type + apply(variant const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return apply_visitor(visitor(geometry2, strategy), geometry1); + } +}; + + +template +struct distance > +{ + template + struct result_type + { + typedef typename mpl::fold< + typename mpl::transform< + typename variant::types, + typename strategy::distance::services::return_type< + Strategy, + typename point_type::type, + typename mpl::lambda >::type + >::type + >::type, + mpl::set0<>, + mpl::insert + >::type possible_result_types; + + typedef typename mpl::if_< + mpl::greater< + mpl::size, + mpl::int_<1> + >, + typename make_variant_over::type, + typename mpl::front::type + >::type type; + }; + + template + struct visitor: static_visitor< + typename result_type::type + > + { + Geometry1 const& m_geometry1; + Strategy const& m_strategy; + + visitor(Geometry1 const& geometry1) + : m_geometry1(geometry1), + m_strategy(strategy) + {} + + template + bool operator()(Geometry2 const& geometry2, typename Strategy) const + { + return dispatch::distance + < + Geometry1, + Geometry2, + Strategy + >::apply(geometry1, geometry2, strategy); + } + }; + + template + static inline typename result_type >::type + apply( + Geometry1 const& geometry1, + const variant& geometry2, + Strategy const& strategy) + { + return apply_visitor(visitor(geometry1, strategy), geometry2); + } +}; + + +template +struct distance, variant > +{ + template + struct result_type + { + template + struct list_of_pairs + : mpl::fold::types, Result, + mpl::push_back > > + {}; + + typedef typename mpl::fold< + typename variant::types, + mpl::vector0<>, + mpl::lambda > + >::type combinations; + + typedef typename mpl::fold< + typename mpl::transform< + typename combinations, + typename strategy::distance::services::return_type< + Strategy, + typename mpl::lambda > >::type, + typename mpl::lambda > >::type + >::type + >::type, + mpl::set0<>, + mpl::insert + >::type possible_result_types; + + typedef typename mpl::if_< + mpl::greater< + mpl::size, + mpl::int_<1> + >, + typename make_variant_over::type, + typename mpl::front::type + >::type type; + }; + + template + struct visitor: static_visitor< + typename result_type::type + > + { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + + template + typename default_distance_result::type operator()( + Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) const + { + return resolve_variant::distance + < + Geometry1, + Geometry2, + Strategy + >::apply(geometry1, geometry2, strategy); + } + }; + + template + static inline typename result_type >::type + apply( + const variant& geometry1, + const variant& geometry2, + Strategy const& strategy) + { + return apply_visitor(visitor(strategy), geometry1, geometry2); + } +}; + +} // namespace resolve_variant + + /*! \brief \brief_calc2{distance} \brief_strategy \ingroup distance @@ -534,12 +791,7 @@ for distance, it is probably so that there is no specialization for return_type<...> for your strategy. */ template -inline typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type +inline typename resolve_variant::distance::result_type::type distance(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) @@ -550,11 +802,10 @@ distance(Geometry1 const& geometry1, detail::throw_on_empty_input(geometry1); detail::throw_on_empty_input(geometry2); - return dispatch::distance + return resolve_variant::distance < Geometry1, - Geometry2, - Strategy + Geometry2 >::apply(geometry1, geometry2, strategy); } @@ -572,8 +823,12 @@ distance(Geometry1 const& geometry1, \qbk{[include reference/algorithms/distance.qbk]} */ template -inline typename default_distance_result::type distance( - Geometry1 const& geometry1, Geometry2 const& geometry2) +inline typename resolve_variant::distance::result_type + < + typename detail::distance::default_strategy::type + >::type +distance(Geometry1 const& geometry1, + Geometry2 const& geometry2) { concept::check(); concept::check(); From 124f783d3b395d536a65b660a365ffebf5a98c37 Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Tue, 13 May 2014 16:40:41 +0200 Subject: [PATCH 02/10] [distance] Add variant tests No finished yet --- .../boost/geometry/algorithms/distance.hpp | 20 +++- include/boost/geometry/util/combine_if.hpp | 62 ++++++++++ test/algorithms/distance.cpp | 111 ++++++++++++++++++ 3 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 include/boost/geometry/util/combine_if.hpp diff --git a/include/boost/geometry/algorithms/distance.hpp b/include/boost/geometry/algorithms/distance.hpp index 685d1f580..42116e4d6 100644 --- a/include/boost/geometry/algorithms/distance.hpp +++ b/include/boost/geometry/algorithms/distance.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ #include #include +#include namespace boost { namespace geometry @@ -255,7 +257,7 @@ struct point_to_polygon // Helper metafunction for default strategy retrieval -template +template struct default_strategy : strategy::distance::services::default_strategy < @@ -263,7 +265,21 @@ struct default_strategy typename point_type::type, typename point_type::type > -{}; +{ +}; + + +template <> +struct default_strategy +{ + template + struct rebind + { + typedef default_strategy type; + }; + + typedef void type; +}; }} // namespace detail::distance diff --git a/include/boost/geometry/util/combine_if.hpp b/include/boost/geometry/util/combine_if.hpp new file mode 100644 index 000000000..052cdec2f --- /dev/null +++ b/include/boost/geometry/util/combine_if.hpp @@ -0,0 +1,62 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// 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. + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP +#define BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP + +#include +#include + + +namespace boost { namespace geometry +{ + +namespace util +{ + + +/*! + \brief Meta-function to generate all the combination of pairs of types + from a given sequence Sequence except those that does not satisfy the + predicate Pred + \ingroup utility +*/ +template +struct combine_if +{ + struct combine + { + template + struct apply + { + typedef typename mpl::fold::type, + mpl::insert >, + mpl::_1 + > + >::type type; + }; + }; + + typedef typename mpl::fold, combine>::type type; +}; + + +} // namespace util + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP diff --git a/test/algorithms/distance.cpp b/test/algorithms/distance.cpp index 597df4f07..e5ad58edb 100644 --- a/test/algorithms/distance.cpp +++ b/test/algorithms/distance.cpp @@ -29,6 +29,8 @@ #include #include +#include + BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian) BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) @@ -313,6 +315,113 @@ void test_large_integers() } } + +namespace boost { namespace geometry { + +namespace test { + +template +struct is_implemented +{ + typedef mpl::true_ type; +}; + +template +struct distance {}; + +template +struct distance, variant > +{ + template + struct result_type + { + //template + //struct list_of_pairs + // : mpl::fold::types, Result, + // mpl::push_back > > + //{}; + + //typedef typename mpl::fold< + // typename variant::types, + // mpl::vector0<>, + // mpl::lambda > + //>::type combinations; + + typedef typename util::combine_if< + typename variant::types, + mpl::quote2 + >::type possible_input_types; + + + //typedef typename mpl::transform< + // possible_input_types, + // typename strategy::distance::services::return_type< + // //Strategy, + // typename Strategy::template rebind, mpl::second >::type, + // typename mpl::lambda > >::type, + // typename mpl::lambda > >::type + // >::type + //>::type possible_result_types; + + //typedef typename mpl::fold< + // typename mpl::transform< + // possible_input_types, + // typename strategy::distance::services::return_type< + // typename Strategy::template rebind, mpl::second >::type, + // typename mpl::lambda > >::type, + // typename mpl::lambda > >::type + // >::type + // >::type, + // mpl::set0<>, + // mpl::insert + //>::type possible_result_types; + + //typedef typename mpl::if_< + // mpl::greater< + // mpl::size, + // mpl::int_<1> + // >, + // typename make_variant_over::type, + // typename mpl::front::type + //>::type type; + }; +}; + +} //namespace test + +}} // namespace boost::geometry + +void test_variant() +{ + typedef bg::model::point point_type; + typedef bg::model::segment segment_type; + typedef boost::variant variant_type; + + point_type point; + std::string const point_li = "POINT(1 3)"; + bg::read_wkt(point_li, point); + + segment_type seg; + std::string const seg_li = "LINESTRING(1 1,4 4)"; + bg::read_wkt(seg_li, seg); + + variant_type v1, v2; + + //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); + //v1 = point; + //v2 = seg; + //BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, seg), 0.0001); + + bg::test::distance::result_type + < + bg::detail::distance::default_strategy<> + >::possible_input_types res; +} + int test_main(int, char* []) { #ifdef TEST_ARRAY @@ -335,5 +444,7 @@ int test_main(int, char* []) test_empty_input >(); + test_variant(); + return 0; } From 3d528db92c72059820689cf409b3a254cae1297b Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Wed, 14 May 2014 16:27:55 +0200 Subject: [PATCH 03/10] [distance] First step to fix tests --- .../boost/geometry/algorithms/distance.hpp | 118 ++++++++++++------ test/algorithms/distance.cpp | 101 ++------------- 2 files changed, 93 insertions(+), 126 deletions(-) diff --git a/include/boost/geometry/algorithms/distance.hpp b/include/boost/geometry/algorithms/distance.hpp index 42116e4d6..4173e3d26 100644 --- a/include/boost/geometry/algorithms/distance.hpp +++ b/include/boost/geometry/algorithms/distance.hpp @@ -525,7 +525,53 @@ struct distance #endif // DOXYGEN_NO_DISPATCH -namespace resolve_variant { +namespace resolve_variant +{ + +namespace detail { namespace distance +{ + +template +struct is_same_dimension_and_coordinate_system +{ + typedef typename mpl::and_< + typename is_same< + typename coordinate_system::type, + typename coordinate_system::type + >::type, + typename is_same< + typename dimension::type, + typename dimension::type + >::type + >::type + type; +}; + + +template +struct is_implemented +{ + typedef typename mpl::not_< + typename is_base_of< + nyi::not_implemented_tag, + geometry::dispatch::distance + >::type + >::type + type; +}; + + +template +struct is_compatible +{ + typedef typename mpl::and_< + typename is_same_dimension_and_coordinate_system::type, + typename is_implemented::type + >::type + type; +}; + +}} // namespace detail::distance template @@ -695,39 +741,44 @@ struct distance, variant struct result_type { - template - struct list_of_pairs - : mpl::fold::types, Result, - mpl::push_back > > - {}; - - typedef typename mpl::fold< + typedef typename util::combine_if< typename variant::types, - mpl::vector0<>, - mpl::lambda > - >::type combinations; + mpl::quote2 + >::type possible_input_types; - typedef typename mpl::fold< - typename mpl::transform< - typename combinations, - typename strategy::distance::services::return_type< - Strategy, - typename mpl::lambda > >::type, - typename mpl::lambda > >::type - >::type - >::type, - mpl::set0<>, - mpl::insert - >::type possible_result_types; + //template + //struct list_of_pairs + // : mpl::fold::types, Result, + // mpl::push_back > > + //{}; - typedef typename mpl::if_< - mpl::greater< - mpl::size, - mpl::int_<1> - >, - typename make_variant_over::type, - typename mpl::front::type - >::type type; + //typedef typename mpl::fold< + // typename variant::types, + // mpl::vector0<>, + // mpl::lambda > + //>::type combinations; + + //typedef typename mpl::fold< + // typename mpl::transform< + // typename combinations, + // typename strategy::distance::services::return_type< + // Strategy, + // typename mpl::lambda > >::type, + // typename mpl::lambda > >::type + // >::type + // >::type, + // mpl::set0<>, + // mpl::insert + //>::type possible_result_types; + + //typedef typename mpl::if_< + // mpl::greater< + // mpl::size, + // mpl::int_<1> + // >, + // typename make_variant_over::type, + // typename mpl::front::type + //>::type type; }; template @@ -839,10 +890,7 @@ distance(Geometry1 const& geometry1, \qbk{[include reference/algorithms/distance.qbk]} */ template -inline typename resolve_variant::distance::result_type - < - typename detail::distance::default_strategy::type - >::type +inline typename default_distance_result::type distance(Geometry1 const& geometry1, Geometry2 const& geometry2) { diff --git a/test/algorithms/distance.cpp b/test/algorithms/distance.cpp index e5ad58edb..1bc8c77da 100644 --- a/test/algorithms/distance.cpp +++ b/test/algorithms/distance.cpp @@ -197,9 +197,6 @@ void test_distance_array_as_linestring() BOOST_CHECK_CLOSE(d, return_type(2.828427), 0.001); } - - - template void test_all() { @@ -316,81 +313,6 @@ void test_large_integers() } -namespace boost { namespace geometry { - -namespace test { - -template -struct is_implemented -{ - typedef mpl::true_ type; -}; - -template -struct distance {}; - -template -struct distance, variant > -{ - template - struct result_type - { - //template - //struct list_of_pairs - // : mpl::fold::types, Result, - // mpl::push_back > > - //{}; - - //typedef typename mpl::fold< - // typename variant::types, - // mpl::vector0<>, - // mpl::lambda > - //>::type combinations; - - typedef typename util::combine_if< - typename variant::types, - mpl::quote2 - >::type possible_input_types; - - - //typedef typename mpl::transform< - // possible_input_types, - // typename strategy::distance::services::return_type< - // //Strategy, - // typename Strategy::template rebind, mpl::second >::type, - // typename mpl::lambda > >::type, - // typename mpl::lambda > >::type - // >::type - //>::type possible_result_types; - - //typedef typename mpl::fold< - // typename mpl::transform< - // possible_input_types, - // typename strategy::distance::services::return_type< - // typename Strategy::template rebind, mpl::second >::type, - // typename mpl::lambda > >::type, - // typename mpl::lambda > >::type - // >::type - // >::type, - // mpl::set0<>, - // mpl::insert - //>::type possible_result_types; - - //typedef typename mpl::if_< - // mpl::greater< - // mpl::size, - // mpl::int_<1> - // >, - // typename make_variant_over::type, - // typename mpl::front::type - //>::type type; - }; -}; - -} //namespace test - -}} // namespace boost::geometry - void test_variant() { typedef bg::model::point point_type; @@ -407,19 +329,16 @@ void test_variant() variant_type v1, v2; - //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); - //v1 = point; - //v2 = seg; - //BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, seg), 0.0001); - - bg::test::distance::result_type - < - bg::detail::distance::default_strategy<> - >::possible_input_types res; + 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); + v1 = point; + v2 = seg; + 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); } int test_main(int, char* []) From 595f6fe4575989ee16600c4e0400cd355a1b83c4 Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 16 May 2014 16:14:50 +0200 Subject: [PATCH 04/10] [distance] Fix some typo and add more tests --- .../algorithms/detail/distance/default_strategies.hpp | 2 +- include/boost/geometry/util/combine_if.hpp | 4 ---- include/boost/geometry/util/is_implemented.hpp | 11 ++--------- test/algorithms/distance.cpp | 4 ++-- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp b/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp index c37367e11..890924984 100644 --- a/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp +++ b/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp @@ -142,4 +142,4 @@ struct default_ps_strategy }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_DEFAULT_STRATEGIES_HPP \ No newline at end of file +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_DEFAULT_STRATEGIES_HPP diff --git a/include/boost/geometry/util/combine_if.hpp b/include/boost/geometry/util/combine_if.hpp index 764845feb..6d8d932a1 100644 --- a/include/boost/geometry/util/combine_if.hpp +++ b/include/boost/geometry/util/combine_if.hpp @@ -1,9 +1,5 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// 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. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library diff --git a/include/boost/geometry/util/is_implemented.hpp b/include/boost/geometry/util/is_implemented.hpp index 30b99a3f4..eace2c181 100644 --- a/include/boost/geometry/util/is_implemented.hpp +++ b/include/boost/geometry/util/is_implemented.hpp @@ -1,14 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. -// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. - -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. - -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// 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. @@ -17,6 +9,7 @@ // 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_IS_IMPLEMENTED_HPP #define BOOST_GEOMETRY_UTIL_IS_IMPLEMENTED_HPP diff --git a/test/algorithms/distance.cpp b/test/algorithms/distance.cpp index ed5856ab4..19d8830c6 100644 --- a/test/algorithms/distance.cpp +++ b/test/algorithms/distance.cpp @@ -311,7 +311,7 @@ template void test_all() { test_distance_point

(); - test_distance_segment

(); + test_distance_segment

(); test_distance_array_as_linestring

(); test_geometry >("POINT(1 3)", "LINESTRING(1 1,4 4)", sqrt(2.0)); @@ -438,7 +438,7 @@ template void test_variant() { typedef bg::model::point point_type; - typedef bg::model::segment segment_type; + typedef bg::model::segment segment_type; typedef boost::variant variant_type; point_type point; From 09a8ba53a75a0e3d59d5437ba812b1914b74c08b Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Mon, 19 May 2014 13:52:09 +0200 Subject: [PATCH 05/10] [distance] Use transform_variant Remove dependency to is_implemented. Update transform_variant to support MPL sequence input. --- .../algorithms/detail/distance/interface.hpp | 70 ++++++++------- .../boost/geometry/algorithms/distance.hpp | 2 +- .../boost/geometry/util/is_implemented.hpp | 79 ++++++++++++++--- .../boost/geometry/util/transform_variant.hpp | 35 ++++++-- test/algorithms/distance.cpp | 19 ++-- test/util/is_implemented.cpp | 88 +++++++++++++++++++ test/util/transform_variant.cpp | 24 ++++- 7 files changed, 255 insertions(+), 62 deletions(-) create mode 100644 test/util/is_implemented.cpp diff --git a/include/boost/geometry/algorithms/detail/distance/interface.hpp b/include/boost/geometry/algorithms/detail/distance/interface.hpp index c797d0666..58337f38b 100644 --- a/include/boost/geometry/algorithms/detail/distance/interface.hpp +++ b/include/boost/geometry/algorithms/detail/distance/interface.hpp @@ -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 #include #include -#include +//#include + +#include +#include +#include namespace boost { namespace geometry @@ -166,30 +171,28 @@ struct distance template struct distance, Strategy> { - // A set of of all variant type combinations that are compatible and implemented - typedef typename util::combine_if - < - typename mpl::vector1, - typename variant::types, - util::is_compatible - >::type possible_input_types; + // A set of all variant type combinations that are compatible and implemented + typedef typename util::combine_if< + typename mpl::vector1, + typename variant::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::always + >::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 >, point_type >, Strategy >, - mpl::back_inserter > - >::type possible_result_types; - - // The (possibly variant) result type - typedef typename compress_variant< - typename make_variant_over< - possible_result_types + mpl::back_inserter > >::type >::type type; }; @@ -205,30 +208,29 @@ struct distance, Geometry2, Strategy> template struct distance, variant, 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::types, typename variant::types, - util::is_compatible + // 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::always >::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 >, point_type >, Strategy >, - mpl::back_inserter > - >::type possible_result_types; - - // The (possibly variant) result type - typedef typename compress_variant< - typename make_variant_over< - possible_result_types + mpl::back_inserter > >::type >::type type; }; diff --git a/include/boost/geometry/algorithms/distance.hpp b/include/boost/geometry/algorithms/distance.hpp index 01a36fd09..dcfe597cd 100644 --- a/include/boost/geometry/algorithms/distance.hpp +++ b/include/boost/geometry/algorithms/distance.hpp @@ -23,4 +23,4 @@ #include #include -#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP \ No newline at end of file +#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP diff --git a/include/boost/geometry/util/is_implemented.hpp b/include/boost/geometry/util/is_implemented.hpp index eace2c181..bf0f3823a 100644 --- a/include/boost/geometry/util/is_implemented.hpp +++ b/include/boost/geometry/util/is_implemented.hpp @@ -15,18 +15,63 @@ #include #include + #include #include +#include +#include + +#include + + namespace boost { namespace geometry { namespace util { +namespace detail +{ +template +struct is_implemented1 + : mpl::not_ + < + typename is_base_of + < + nyi::not_implemented_tag, + //typename mpl::apply1::type + Algorithm + >::type + > +{}; + + +template +struct is_implemented2 + : mpl::not_ + < + typename is_base_of + < + nyi::not_implemented_tag, + //typename mpl::apply2::type + Algorithm + >::type + > +{}; + + +} // namespace detail + + +/*! + \brief Meta-function to check whether two geometry types + have the same dimensions and coordinate systems + \ingroup utility +*/ template -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 -struct is_implemented - : mpl::not_ +/*! + \brief Meta-function to check whether an Unary Algorithm + is implemented for the given geometry types + \ingroup utility +*/ +template +struct is_implemented1 + : mpl::and_ < - typename is_base_of - < - nyi::not_implemented_tag, - geometry::dispatch::distance - >::type + typename detail::is_implemented1::type > {}; -template -struct is_compatible +/*! + \brief Meta-function to check whether an Binary Algorithm + is implemented for the given geometry types + \ingroup utility +*/ +template +struct is_implemented2 : mpl::and_ < - typename is_same_dimension_and_coordinate_system::type, - typename is_implemented::type + // is_compatible is necessary because of some MPL_ASSERT + // shortcuting the not_implemented class when dimension / coordinate system differs + typename is_compatible2::type, + typename detail::is_implemented2::type > {}; diff --git a/include/boost/geometry/util/transform_variant.hpp b/include/boost/geometry/util/transform_variant.hpp index 21ce501f2..9e4a7aa15 100644 --- a/include/boost/geometry/util/transform_variant.hpp +++ b/include/boost/geometry/util/transform_variant.hpp @@ -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 types; + typedef transform_variant > transformed; + typedef variant result; + BOOST_MPL_ASSERT(( equal )); + \endcode +*/ +template +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 )); \endcode */ - -template -struct transform_variant: +template +struct transform_variant, Op, boost::mpl::na> : make_variant_over< typename mpl::transform< - typename Variant::types, + typename variant::types, Op >::type > diff --git a/test/algorithms/distance.cpp b/test/algorithms/distance.cpp index 19d8830c6..76775b969 100644 --- a/test/algorithms/distance.cpp +++ b/test/algorithms/distance.cpp @@ -36,7 +36,6 @@ #include #include -// includes for variant #include BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian) @@ -363,7 +362,6 @@ void test_all() test_geometry >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); test_distance_linear >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); - } template @@ -439,7 +437,8 @@ void test_variant() { typedef bg::model::point point_type; typedef bg::model::segment segment_type; - typedef boost::variant variant_type; + typedef bg::model::box box_type; + typedef boost::variant 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 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* []) diff --git a/test/util/is_implemented.cpp b/test/util/is_implemented.cpp new file mode 100644 index 000000000..3eed994b4 --- /dev/null +++ b/test/util/is_implemented.cpp @@ -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 + +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace services +{ + + +template struct tag +{ + + typedef not_implemented type; + +}; + +}} // namespace strategy::services + + +template +< + typename Geometry1, typename Geometry2, + typename Strategy, + typename Tag1 = typename tag_cast::type, multi_tag>::type, + typename Tag2 = typename tag_cast::type, multi_tag>::type, + typename StrategyTag = typename strategy::services::tag::type, + bool Reverse = reverse_dispatch::type::value +> +struct algorithm_archetype + : not_implemented<> +{}; + + +struct strategy_archetype +{ + template + static void apply(Geometry1, Geometry2) {} +}; + + +}} // namespace boost::geometry + + +int test_main(int, char* []) +{ + typedef bg::model::d2::point_xy point_type; + + BOOST_MPL_ASSERT(( + boost::is_same< + bg::util::is_implemented2 + < + point_type, point_type, + bg::algorithm_archetype + >::type, + boost::mpl::false_ + > + )); + + return 0; +} diff --git a/test/util/transform_variant.cpp b/test/util/transform_variant.cpp index 6157ee353..4594e591a 100644 --- a/test/util/transform_variant.cpp +++ b/test/util/transform_variant.cpp @@ -39,12 +39,30 @@ void check(boost::variant) int test_main(int, char* []) { - typedef typename boost::geometry::transform_variant< + // Transform Variant to Variant + typedef boost::geometry::transform_variant< boost::variant, boost::add_pointer<_> - >::type transformed; + >::type transformed1; - check >(transformed()); + check >(transformed1()); + + // Transform Sequence to Variant (without inserter) + typedef boost::geometry::transform_variant< + boost::mpl::vector, + boost::add_pointer<_> + >::type transformed2; + + check >(transformed2()); + + // Transform Sequence to Variant (with inserter) + typedef boost::geometry::transform_variant< + boost::mpl::vector, + boost::add_pointer<_>, + boost::mpl::back_inserter > + >::type transformed3; + + check >(transformed3()); return 0; } From eb643847373f79018b4a108af754bd5b93530307 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 21 May 2014 17:18:24 +0200 Subject: [PATCH 06/10] [test] Temporarily disable rescale test --- test/policies/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/policies/Jamfile.v2 b/test/policies/Jamfile.v2 index 22c58c89c..503817813 100644 --- a/test/policies/Jamfile.v2 +++ b/test/policies/Jamfile.v2 @@ -11,5 +11,5 @@ test-suite boost-geometry-policies : [ run compare.cpp ] - [ run rescale_policy.cpp ] +# [ run rescale_policy.cpp ] ; From 3474244d0a91d63752cd8a7b683fd013da030750 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 22 May 2014 17:24:31 +0200 Subject: [PATCH 07/10] [index] Varian-based nodes used in the rtree by default. This should fix the crash when the rtree is used in the shared memory reported in this thread: http://boost-geometry.203548.n3.nabble.com/rtree-crash-when-used-with-inter-process-td4026037.html --- .../boost/geometry/index/detail/rtree/options.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/options.hpp b/include/boost/geometry/index/detail/rtree/options.hpp index b1bb60df1..b7947402c 100644 --- a/include/boost/geometry/index/detail/rtree/options.hpp +++ b/include/boost/geometry/index/detail/rtree/options.hpp @@ -66,7 +66,7 @@ struct options_type< index::linear > choose_by_content_diff_tag, split_default_tag, linear_tag, - node_d_mem_static_tag + node_s_mem_static_tag > type; }; @@ -79,7 +79,7 @@ struct options_type< index::quadratic > choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_d_mem_static_tag + node_s_mem_static_tag > type; }; @@ -92,7 +92,7 @@ struct options_type< index::rstar type; }; @@ -105,7 +105,7 @@ struct options_type< index::rstar type; //}; @@ -118,7 +118,7 @@ struct options_type< index::dynamic_linear > choose_by_content_diff_tag, split_default_tag, linear_tag, - node_d_mem_dynamic_tag + node_s_mem_dynamic_tag > type; }; @@ -131,7 +131,7 @@ struct options_type< index::dynamic_quadratic > choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_d_mem_dynamic_tag + node_s_mem_dynamic_tag > type; }; @@ -144,7 +144,7 @@ struct options_type< index::dynamic_rstar > choose_by_overlap_diff_tag, split_default_tag, rstar_tag, - node_d_mem_dynamic_tag + node_s_mem_dynamic_tag > type; }; From 79cd3df9235fb7bda33a728a1bfb7fe94d80b34f Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 23 May 2014 14:09:23 +0200 Subject: [PATCH 08/10] [distance] Support different variant type Add support for different variant type as parameters --- .../algorithms/detail/distance/interface.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/distance/interface.hpp b/include/boost/geometry/algorithms/detail/distance/interface.hpp index 58337f38b..53db9be12 100644 --- a/include/boost/geometry/algorithms/detail/distance/interface.hpp +++ b/include/boost/geometry/algorithms/detail/distance/interface.hpp @@ -360,16 +360,16 @@ struct distance > }; -template -struct distance, variant > +template +struct distance, variant > { template struct visitor: static_visitor < typename result_of::distance < - variant, - variant, + variant, + variant, Strategy > ::type @@ -400,14 +400,14 @@ struct distance, variant static inline typename result_of::distance < - variant, - variant, + variant, + variant, Strategy > ::type apply( - const variant& geometry1, - const variant& geometry2, + const variant& geometry1, + const variant& geometry2, Strategy const& strategy) { return apply_visitor(visitor(strategy), geometry1, geometry2); From 5cc480d2c297990e8f3598ea2bf6809997443b8e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 23 May 2014 14:18:47 +0200 Subject: [PATCH 09/10] [index] Remove unneeded template keyword from member function call --- .../geometry/index/detail/rtree/node/node_s_mem_static.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp index d5d68cbd1..5df869c95 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp @@ -175,7 +175,7 @@ struct create_node< return create_static_node< typename Allocators::node_pointer, static_internal_node - >::template apply(allocators.node_allocator()); + >::apply(allocators.node_allocator()); } }; @@ -191,7 +191,7 @@ struct create_node< return create_static_node< typename Allocators::node_pointer, static_leaf - >::template apply(allocators.node_allocator()); + >::apply(allocators.node_allocator()); } }; From c9edff5e311dd6960c98780b136fe05002c41a35 Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 23 May 2014 17:00:03 +0200 Subject: [PATCH 10/10] [distance] Remove global is_implemented --- .../boost/geometry/util/is_implemented.hpp | 128 ------------------ 1 file changed, 128 deletions(-) delete mode 100644 include/boost/geometry/util/is_implemented.hpp diff --git a/include/boost/geometry/util/is_implemented.hpp b/include/boost/geometry/util/is_implemented.hpp deleted file mode 100644 index bf0f3823a..000000000 --- a/include/boost/geometry/util/is_implemented.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// 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) - - -#ifndef BOOST_GEOMETRY_UTIL_IS_IMPLEMENTED_HPP -#define BOOST_GEOMETRY_UTIL_IS_IMPLEMENTED_HPP - -#include -#include - -#include -#include - -#include -#include - -#include - - -namespace boost { namespace geometry -{ - -namespace util -{ - -namespace detail -{ - -template -struct is_implemented1 - : mpl::not_ - < - typename is_base_of - < - nyi::not_implemented_tag, - //typename mpl::apply1::type - Algorithm - >::type - > -{}; - - -template -struct is_implemented2 - : mpl::not_ - < - typename is_base_of - < - nyi::not_implemented_tag, - //typename mpl::apply2::type - Algorithm - >::type - > -{}; - - -} // namespace detail - - -/*! - \brief Meta-function to check whether two geometry types - have the same dimensions and coordinate systems - \ingroup utility -*/ -template -struct is_compatible2 - : mpl::and_ - < - typename is_same - < - typename coordinate_system::type, - typename coordinate_system::type - >::type, - typename is_same - < - typename dimension::type, - typename dimension::type - >::type - > -{}; - - -/*! - \brief Meta-function to check whether an Unary Algorithm - is implemented for the given geometry types - \ingroup utility -*/ -template -struct is_implemented1 - : mpl::and_ - < - typename detail::is_implemented1::type - > -{}; - - -/*! - \brief Meta-function to check whether an Binary Algorithm - is implemented for the given geometry types - \ingroup utility -*/ -template -struct is_implemented2 - : mpl::and_ - < - // is_compatible is necessary because of some MPL_ASSERT - // shortcuting the not_implemented class when dimension / coordinate system differs - typename is_compatible2::type, - typename detail::is_implemented2::type - > -{}; - - -} // namespace util - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_UTIL_IS_IMPLEMENTED_HPP