From 2a819b81efd4a77304af180483d393c8ad6f15a8 Mon Sep 17 00:00:00 2001 From: Samuel Debionne Date: Wed, 21 May 2014 08:31:22 +0200 Subject: [PATCH 1/7] [assign] Add variant support --- include/boost/geometry/algorithms/assign.hpp | 154 ++++++++++++++++--- 1 file changed, 136 insertions(+), 18 deletions(-) diff --git a/include/boost/geometry/algorithms/assign.hpp b/include/boost/geometry/algorithms/assign.hpp index fd23f1ddb..2ab86b05a 100644 --- a/include/boost/geometry/algorithms/assign.hpp +++ b/include/boost/geometry/algorithms/assign.hpp @@ -40,6 +40,8 @@ #include +#include + namespace boost { namespace geometry { @@ -121,6 +123,138 @@ inline void assign_zero(Geometry& geometry) >::apply(geometry); } + +namespace resolve_variant +{ + template + struct assign + { + static inline void + apply( + const Geometry1& geometry1, + const Geometry2& geometry2) + { + concept::check_concepts_and_equal_dimensions(); + + bool const same_point_order = + point_order::value == point_order::value; + bool const same_closure = + closure::value == closure::value; + + BOOST_MPL_ASSERT_MSG + ( + same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER + , (types) + ); + BOOST_MPL_ASSERT_MSG + ( + same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE + , (types) + ); + + dispatch::convert::apply(geometry2, geometry1); + } + }; + + + template + struct assign, Geometry2> + { + template + struct visitor: static_visitor + { + Geometry2 const& m_geometry2; + + visitor(Geometry2 const& geometry2) + : m_geometry2(geometry2) + {} + + template + result_type operator()(Geometry1 const& geometry1) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (geometry1, m_geometry2); + } + }; + + static inline void + apply(variant const& geometry1, + Geometry2 const& geometry2) + { + return apply_visitor(visitor(geometry2), geometry1); + } + }; + + + template + struct assign > + { + template + struct visitor: static_visitor + { + Geometry1 const& m_geometry1; + + visitor(Geometry1 const& geometry1) + : m_geometry1(geometry1) + {} + + template + result_type operator()(Geometry2 const& geometry2) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (m_geometry1, geometry2); + } + }; + + static inline void + apply( + Geometry1 const& geometry1, + const variant& geometry2) + { + return apply_visitor(visitor(geometry1), geometry2); + } + }; + + + template + struct assign, variant > + { + struct visitor: static_visitor + { + template + result_type operator()( + Geometry1 const& geometry1, + Geometry2 const& geometry2) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (geometry1, geometry2); + } + }; + + static inline void + apply( + const variant& geometry1, + const variant& geometry2) + { + return apply_visitor(visitor(), geometry1, geometry2); + } + }; + +} // namespace resolve_variant + + /*! \brief Assigns one geometry to another geometry \details The assign algorithm assigns one geometry, e.g. a BOX, to another @@ -143,24 +277,8 @@ template inline void assign(Geometry1& geometry1, Geometry2 const& geometry2) { concept::check_concepts_and_equal_dimensions(); - - bool const same_point_order = - point_order::value == point_order::value; - bool const same_closure = - closure::value == closure::value; - - BOOST_MPL_ASSERT_MSG - ( - same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER - , (types) - ); - BOOST_MPL_ASSERT_MSG - ( - same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE - , (types) - ); - - dispatch::convert::apply(geometry2, geometry1); + + resolve_variant::assign::apply(geometry2, geometry1); } From ddc649a492721afd1ec9b2c7146a2751e49fdd39 Mon Sep 17 00:00:00 2001 From: Samuel Debionne Date: Wed, 21 May 2014 20:02:30 +0200 Subject: [PATCH 2/7] [assign] Fix compiler errors --- include/boost/geometry/algorithms/assign.hpp | 48 ++++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/include/boost/geometry/algorithms/assign.hpp b/include/boost/geometry/algorithms/assign.hpp index 2ab86b05a..dd570bcf3 100644 --- a/include/boost/geometry/algorithms/assign.hpp +++ b/include/boost/geometry/algorithms/assign.hpp @@ -131,26 +131,26 @@ namespace resolve_variant { static inline void apply( - const Geometry1& geometry1, + Geometry1& geometry1, const Geometry2& geometry2) { concept::check_concepts_and_equal_dimensions(); bool const same_point_order = - point_order::value == point_order::value; + point_order::value == point_order::value; bool const same_closure = - closure::value == closure::value; + closure::value == closure::value; BOOST_MPL_ASSERT_MSG ( - same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER - , (types) - ); + same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER + , (types) + ); BOOST_MPL_ASSERT_MSG ( - same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE - , (types) - ); + same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE + , (types) + ); dispatch::convert::apply(geometry2, geometry1); } @@ -160,7 +160,6 @@ namespace resolve_variant template struct assign, Geometry2> { - template struct visitor: static_visitor { Geometry2 const& m_geometry2; @@ -170,22 +169,22 @@ namespace resolve_variant {} template - result_type operator()(Geometry1 const& geometry1) const + result_type operator()(Geometry1& geometry1) const { return assign < - Geometry1, - Geometry2 + Geometry1, + Geometry2 >::apply (geometry1, m_geometry2); } }; static inline void - apply(variant const& geometry1, + apply(variant& geometry1, Geometry2 const& geometry2) { - return apply_visitor(visitor(geometry2), geometry1); + return apply_visitor(visitor(geometry2), geometry1); } }; @@ -193,10 +192,9 @@ namespace resolve_variant template struct assign > { - template struct visitor: static_visitor { - Geometry1 const& m_geometry1; + Geometry1& m_geometry1; visitor(Geometry1 const& geometry1) : m_geometry1(geometry1) @@ -207,8 +205,8 @@ namespace resolve_variant { return assign < - Geometry1, - Geometry2 + Geometry1, + Geometry2 >::apply (m_geometry1, geometry2); } @@ -216,10 +214,10 @@ namespace resolve_variant static inline void apply( - Geometry1 const& geometry1, + Geometry1& geometry1, const variant& geometry2) { - return apply_visitor(visitor(geometry1), geometry2); + return apply_visitor(visitor(geometry1), geometry2); } }; @@ -236,8 +234,8 @@ namespace resolve_variant { return assign < - Geometry1, - Geometry2 + Geometry1, + Geometry2 >::apply (geometry1, geometry2); } @@ -245,7 +243,7 @@ namespace resolve_variant static inline void apply( - const variant& geometry1, + variant& geometry1, const variant& geometry2) { return apply_visitor(visitor(), geometry1, geometry2); @@ -278,7 +276,7 @@ inline void assign(Geometry1& geometry1, Geometry2 const& geometry2) { concept::check_concepts_and_equal_dimensions(); - resolve_variant::assign::apply(geometry2, geometry1); + resolve_variant::assign::apply(geometry1, geometry2); } From 594add5e1b93d6f38271ed748ae14deff6accadf Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Thu, 22 May 2014 16:32:47 +0200 Subject: [PATCH 3/7] [assign] Add tests for variants --- include/boost/geometry/algorithms/assign.hpp | 224 +++++++++---------- test/algorithms/assign.cpp | 65 ++++++ 2 files changed, 177 insertions(+), 112 deletions(-) diff --git a/include/boost/geometry/algorithms/assign.hpp b/include/boost/geometry/algorithms/assign.hpp index dd570bcf3..bcec721e7 100644 --- a/include/boost/geometry/algorithms/assign.hpp +++ b/include/boost/geometry/algorithms/assign.hpp @@ -126,129 +126,128 @@ inline void assign_zero(Geometry& geometry) namespace resolve_variant { - template - struct assign + +template +struct assign +{ + static inline void + apply( + Geometry1& geometry1, + const Geometry2& geometry2) { - static inline void - apply( - Geometry1& geometry1, - const Geometry2& geometry2) + concept::check_concepts_and_equal_dimensions(); + + bool const same_point_order = + point_order::value == point_order::value; + bool const same_closure = + closure::value == closure::value; + + BOOST_MPL_ASSERT_MSG + ( + same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER + , (types) + ); + BOOST_MPL_ASSERT_MSG + ( + same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE + , (types) + ); + + dispatch::convert::apply(geometry2, geometry1); + } +}; + + +template +struct assign, Geometry2> +{ + struct visitor: static_visitor + { + Geometry2 const& m_geometry2; + + visitor(Geometry2 const& geometry2) + : m_geometry2(geometry2) + {} + + template + result_type operator()(Geometry1& geometry1) const { - concept::check_concepts_and_equal_dimensions(); - - bool const same_point_order = - point_order::value == point_order::value; - bool const same_closure = - closure::value == closure::value; - - BOOST_MPL_ASSERT_MSG - ( - same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER - , (types) - ); - BOOST_MPL_ASSERT_MSG - ( - same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE - , (types) - ); - - dispatch::convert::apply(geometry2, geometry1); + return assign + < + Geometry1, + Geometry2 + >::apply + (geometry1, m_geometry2); } }; - - - template - struct assign, Geometry2> - { - struct visitor: static_visitor - { - Geometry2 const& m_geometry2; - - visitor(Geometry2 const& geometry2) - : m_geometry2(geometry2) - {} - - template - result_type operator()(Geometry1& geometry1) const - { - return assign - < - Geometry1, - Geometry2 - >::apply - (geometry1, m_geometry2); - } - }; - static inline void - apply(variant& geometry1, - Geometry2 const& geometry2) - { - return apply_visitor(visitor(geometry2), geometry1); - } - }; - - - template - struct assign > + static inline void + apply(variant& geometry1, + Geometry2 const& geometry2) { - struct visitor: static_visitor - { - Geometry1& m_geometry1; - - visitor(Geometry1 const& geometry1) - : m_geometry1(geometry1) - {} - - template - result_type operator()(Geometry2 const& geometry2) const - { - return assign - < - Geometry1, - Geometry2 - >::apply - (m_geometry1, geometry2); - } - }; - - static inline void - apply( - Geometry1& geometry1, - const variant& geometry2) - { - return apply_visitor(visitor(geometry1), geometry2); - } - }; + return apply_visitor(visitor(geometry2), geometry1); + } +}; - template - struct assign, variant > +template +struct assign > +{ + struct visitor: static_visitor { - struct visitor: static_visitor + Geometry1& m_geometry1; + + visitor(Geometry1 const& geometry1) + : m_geometry1(geometry1) + {} + + template + result_type operator()(Geometry2 const& geometry2) const { - template - result_type operator()( - Geometry1 const& geometry1, - Geometry2 const& geometry2) const - { - return assign - < - Geometry1, - Geometry2 - >::apply - (geometry1, geometry2); - } - }; - - static inline void - apply( - variant& geometry1, - const variant& geometry2) - { - return apply_visitor(visitor(), geometry1, geometry2); + return assign + < + Geometry1, + Geometry2 + >::apply + (m_geometry1, geometry2); } }; + + static inline void + apply(Geometry1& geometry1, + variant const& geometry2) + { + return apply_visitor(visitor(geometry1), geometry2); + } +}; + + +template +struct assign, variant > +{ + struct visitor: static_visitor + { + template + result_type operator()( + Geometry1& geometry1, + Geometry2 const& geometry2) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (geometry1, geometry2); + } + }; + + static inline void + apply(variant& geometry1, + variant const& geometry2) + { + return apply_visitor(visitor(), geometry1, geometry2); + } +}; } // namespace resolve_variant @@ -274,7 +273,8 @@ geometry, e.g. a RING. This only works if it is possible and applicable. template inline void assign(Geometry1& geometry1, Geometry2 const& geometry2) { - concept::check_concepts_and_equal_dimensions(); + concept::check(); + concept::check(); resolve_variant::assign::apply(geometry1, geometry2); } diff --git a/test/algorithms/assign.cpp b/test/algorithms/assign.cpp index a64f4010d..8a48d78de 100644 --- a/test/algorithms/assign.cpp +++ b/test/algorithms/assign.cpp @@ -189,6 +189,70 @@ void test_assign_conversion() } +template +void test_assign_conversion_variant() +{ + typedef bg::model::box

box_type; + typedef bg::model::ring

ring_type; + typedef bg::model::polygon

polygon_type; + + P p; + bg::assign_values(p, 1, 2); + + box_type b; + bg::assign(boost::variant(b), p); + + BOOST_CHECK_CLOSE((bg::get<0, 0>(b)), 1.0, 0.001); + BOOST_CHECK_CLOSE((bg::get<0, 1>(b)), 2.0, 0.001); + BOOST_CHECK_CLOSE((bg::get<1, 0>(b)), 1.0, 0.001); + BOOST_CHECK_CLOSE((bg::get<1, 1>(b)), 2.0, 0.001); + + + bg::set(b, 1); + bg::set(b, 2); + bg::set(b, 3); + bg::set(b, 4); + + ring_type ring; + bg::assign(boost::variant(ring), boost::variant(b)); + + { + typedef bg::model::ring ring_type_ccw; + ring_type_ccw ring_ccw; + // Should NOT compile (currently): bg::assign(ring_ccw, ring); + + } + + typename boost::range_const_iterator::type it = ring.begin(); + BOOST_CHECK_CLOSE(bg::get<0>(*it), 1.0, 0.001); + BOOST_CHECK_CLOSE(bg::get<1>(*it), 2.0, 0.001); + it++; + BOOST_CHECK_CLOSE(bg::get<0>(*it), 1.0, 0.001); + BOOST_CHECK_CLOSE(bg::get<1>(*it), 4.0, 0.001); + it++; + BOOST_CHECK_CLOSE(bg::get<0>(*it), 3.0, 0.001); + BOOST_CHECK_CLOSE(bg::get<1>(*it), 4.0, 0.001); + it++; + BOOST_CHECK_CLOSE(bg::get<0>(*it), 3.0, 0.001); + BOOST_CHECK_CLOSE(bg::get<1>(*it), 2.0, 0.001); + it++; + BOOST_CHECK_CLOSE(bg::get<0>(*it), 1.0, 0.001); + BOOST_CHECK_CLOSE(bg::get<1>(*it), 2.0, 0.001); + + BOOST_CHECK_EQUAL(ring.size(), 5u); + + + polygon_type polygon; + + bg::assign(boost::variant(polygon), boost::variant(ring)); + BOOST_CHECK_EQUAL(bg::num_points(polygon), 5u); + + ring_type ring2; + bg::assign(boost::variant(ring2), boost::variant(polygon)); + BOOST_CHECK_EQUAL(bg::num_points(ring2), 5u); +} + + template void test_assign_point_2d() { @@ -225,6 +289,7 @@ int test_main(int, char* []) test_assign_point_2d >(); test_assign_conversion >(); + test_assign_conversion_variant >(); // Segment (currently) cannot handle array's because derived from std::pair From 999fdff2ebe666f26b9b36b86c993c7f25575c28 Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 23 May 2014 10:12:39 +0200 Subject: [PATCH 4/7] [assign] Add copyright notice --- include/boost/geometry/algorithms/assign.hpp | 1 + test/algorithms/assign.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/include/boost/geometry/algorithms/assign.hpp b/include/boost/geometry/algorithms/assign.hpp index bcec721e7..50f30e816 100644 --- a/include/boost/geometry/algorithms/assign.hpp +++ b/include/boost/geometry/algorithms/assign.hpp @@ -3,6 +3,7 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// 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. diff --git a/test/algorithms/assign.cpp b/test/algorithms/assign.cpp index 8a48d78de..fbdf3785f 100644 --- a/test/algorithms/assign.cpp +++ b/test/algorithms/assign.cpp @@ -4,6 +4,7 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// 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. From 9e61d9d75957df5ce82c86358f815ecc42dfb553 Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 23 May 2014 10:18:17 +0200 Subject: [PATCH 5/7] [assign] Fix the variant tests Reference was missing. --- test/algorithms/assign.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/algorithms/assign.cpp b/test/algorithms/assign.cpp index fbdf3785f..df8901324 100644 --- a/test/algorithms/assign.cpp +++ b/test/algorithms/assign.cpp @@ -201,7 +201,7 @@ void test_assign_conversion_variant() bg::assign_values(p, 1, 2); box_type b; - bg::assign(boost::variant(b), p); + bg::assign(boost::variant(b), p); BOOST_CHECK_CLOSE((bg::get<0, 0>(b)), 1.0, 0.001); BOOST_CHECK_CLOSE((bg::get<0, 1>(b)), 2.0, 0.001); @@ -215,7 +215,7 @@ void test_assign_conversion_variant() bg::set(b, 4); ring_type ring; - bg::assign(boost::variant(ring), boost::variant(b)); + bg::assign(boost::variant(ring), boost::variant(b)); { typedef bg::model::ring ring_type_ccw; @@ -245,11 +245,11 @@ void test_assign_conversion_variant() polygon_type polygon; - bg::assign(boost::variant(polygon), boost::variant(ring)); + bg::assign(boost::variant(polygon), boost::variant(ring)); BOOST_CHECK_EQUAL(bg::num_points(polygon), 5u); ring_type ring2; - bg::assign(boost::variant(ring2), boost::variant(polygon)); + bg::assign(boost::variant(ring2), boost::variant(polygon)); BOOST_CHECK_EQUAL(bg::num_points(ring2), 5u); } From 55e54692b990fefc9bc0aaa53cbec41247a4712d Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 23 May 2014 10:24:13 +0200 Subject: [PATCH 6/7] [assign] Rename the variant template parameters Was T1 and T2 but that could eventually be a problem if the user defines BOOST_VARIANT_LIMIT_TYPES > 10. --- include/boost/geometry/algorithms/assign.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/algorithms/assign.hpp b/include/boost/geometry/algorithms/assign.hpp index 50f30e816..0d19f6ca9 100644 --- a/include/boost/geometry/algorithms/assign.hpp +++ b/include/boost/geometry/algorithms/assign.hpp @@ -223,8 +223,8 @@ struct assign > }; -template -struct assign, variant > +template +struct assign, variant > { struct visitor: static_visitor { @@ -243,8 +243,8 @@ struct assign, variant& geometry1, - variant const& geometry2) + apply(variant& geometry1, + variant const& geometry2) { return apply_visitor(visitor(), geometry1, geometry2); } From 97508183e1cc0538d8bb2596755dd0c8cea8a57f Mon Sep 17 00:00:00 2001 From: Samuel Debione Date: Fri, 23 May 2014 16:34:17 +0200 Subject: [PATCH 7/7] [assign] Move concept check --- include/boost/geometry/algorithms/assign.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/boost/geometry/algorithms/assign.hpp b/include/boost/geometry/algorithms/assign.hpp index 0d19f6ca9..f7b8679f1 100644 --- a/include/boost/geometry/algorithms/assign.hpp +++ b/include/boost/geometry/algorithms/assign.hpp @@ -136,6 +136,8 @@ struct assign Geometry1& geometry1, const Geometry2& geometry2) { + concept::check(); + concept::check(); concept::check_concepts_and_equal_dimensions(); bool const same_point_order = @@ -274,9 +276,6 @@ geometry, e.g. a RING. This only works if it is possible and applicable. template inline void assign(Geometry1& geometry1, Geometry2 const& geometry2) { - concept::check(); - concept::check(); - resolve_variant::assign::apply(geometry1, geometry2); }