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; }