Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86619 - in trunk: boost/geometry/algorithms boost/geometry/multi/algorithms libs/geometry/test/algorithms
From: bruno.lalande_at_[hidden]
Date: 2013-11-11 11:29:00


Author: bruno.lalande
Date: 2013-11-11 11:29:00 EST (Mon, 11 Nov 2013)
New Revision: 86619
URL: http://svn.boost.org/trac/boost/changeset/86619

Log:
Made perimeter algorithm variant-aware.

Text files modified:
   trunk/boost/geometry/algorithms/perimeter.hpp | 114 ++++++++++++++++++++++++++++++++-------
   trunk/boost/geometry/multi/algorithms/perimeter.hpp | 2
   trunk/libs/geometry/test/algorithms/test_perimeter.hpp | 6 +
   3 files changed, 100 insertions(+), 22 deletions(-)

Modified: trunk/boost/geometry/algorithms/perimeter.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/perimeter.hpp Mon Nov 11 10:41:01 2013 (r86618)
+++ trunk/boost/geometry/algorithms/perimeter.hpp 2013-11-11 11:29:00 EST (Mon, 11 Nov 2013) (r86619)
@@ -15,14 +15,20 @@
 #define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
 
 
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/strategies/default_length_result.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
 #include <boost/geometry/algorithms/length.hpp>
 #include <boost/geometry/algorithms/detail/calculate_null.hpp>
 #include <boost/geometry/algorithms/detail/calculate_sum.hpp>
 // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/default_length_result.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/compress_variant.hpp>
+#include <boost/geometry/util/transform_variant.hpp>
 
 
 namespace boost { namespace geometry
@@ -78,6 +84,86 @@
 #endif // DOXYGEN_NO_DISPATCH
 
 
+namespace resolve_strategy {
+
+struct perimeter
+{
+ template <typename Geometry, typename Strategy>
+ static inline typename default_length_result<Geometry>::type
+ apply(Geometry const& geometry, Strategy const& strategy)
+ {
+ return dispatch::perimeter<Geometry>::apply(geometry, strategy);
+ }
+
+ template <typename Geometry>
+ static inline typename default_length_result<Geometry>::type
+ apply(Geometry const& geometry, default_strategy)
+ {
+ typedef typename strategy::distance::services::default_strategy
+ <
+ point_tag,
+ typename point_type<Geometry>::type
+ >::type strategy_type;
+
+ return dispatch::perimeter<Geometry>::apply(geometry, strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+
+namespace resolve_variant {
+
+template <typename Geometry>
+struct perimeter
+{
+ typedef typename default_length_result<Geometry>::type result_type;
+
+ template <typename Strategy>
+ static inline result_type
+ apply(Geometry const& geometry, Strategy const& strategy)
+ {
+ concept::check<Geometry const>();
+ return resolve_strategy::perimeter::apply(geometry, strategy);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct perimeter<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ typedef typename compress_variant<
+ typename transform_variant<
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
+ default_length_result<boost::mpl::placeholders::_>
+ >::type
+ >:: type result_type;
+
+ template <typename Strategy>
+ struct visitor: boost::static_visitor<result_type>
+ {
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy): m_strategy(strategy) {}
+
+ template <typename Geometry>
+ result_type operator()(Geometry const& geometry) const
+ {
+ return perimeter<Geometry>::apply(geometry, m_strategy);
+ }
+ };
+
+ template <typename Strategy>
+ static inline result_type
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ Strategy const& strategy)
+ {
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
 /*!
 \brief \brief_calc{perimeter}
 \ingroup perimeter
@@ -90,20 +176,11 @@
 \qbk{[include reference/algorithms/perimeter.qbk]}
  */
 template<typename Geometry>
-inline typename default_length_result<Geometry>::type perimeter(
+inline typename resolve_variant::perimeter<Geometry>::result_type perimeter(
         Geometry const& geometry)
 {
- concept::check<Geometry const>();
-
- typedef typename point_type<Geometry>::type point_type;
- typedef typename strategy::distance::services::default_strategy
- <
- point_tag, point_type
- >::type strategy_type;
-
     // detail::throw_on_empty_input(geometry);
-
- return dispatch::perimeter<Geometry>::apply(geometry, strategy_type());
+ return resolve_variant::perimeter<Geometry>::apply(geometry, default_strategy());
 }
 
 /*!
@@ -121,14 +198,11 @@
 \qbk{[include reference/algorithms/perimeter.qbk]}
  */
 template<typename Geometry, typename Strategy>
-inline typename default_length_result<Geometry>::type perimeter(
+inline typename resolve_variant::perimeter<Geometry>::result_type perimeter(
         Geometry const& geometry, Strategy const& strategy)
 {
- concept::check<Geometry const>();
-
     // detail::throw_on_empty_input(geometry);
-
- return dispatch::perimeter<Geometry>::apply(geometry, strategy);
+ return resolve_variant::perimeter<Geometry>::apply(geometry, strategy);
 }
 
 }} // namespace boost::geometry

Modified: trunk/boost/geometry/multi/algorithms/perimeter.hpp
==============================================================================
--- trunk/boost/geometry/multi/algorithms/perimeter.hpp Mon Nov 11 10:41:01 2013 (r86618)
+++ trunk/boost/geometry/multi/algorithms/perimeter.hpp 2013-11-11 11:29:00 EST (Mon, 11 Nov 2013) (r86619)
@@ -35,7 +35,7 @@
 struct perimeter<MultiPolygon, multi_polygon_tag> : detail::multi_sum
 {
     template <typename Strategy>
- static inline typename default_length_result<MultiPolygon>::type
+ static inline typename resolve_variant::perimeter<MultiPolygon>::result_type
     apply(MultiPolygon const& multi, Strategy const& strategy)
     {
         return multi_sum::apply

Modified: trunk/libs/geometry/test/algorithms/test_perimeter.hpp
==============================================================================
--- trunk/libs/geometry/test/algorithms/test_perimeter.hpp Mon Nov 11 10:41:01 2013 (r86618)
+++ trunk/libs/geometry/test/algorithms/test_perimeter.hpp 2013-11-11 11:29:00 EST (Mon, 11 Nov 2013) (r86619)
@@ -10,6 +10,7 @@
 #define BOOST_GEOMETRY_TEST_PERIMETER_HPP
 
 
+#include <boost/typeof/typeof.hpp>
 #include <boost/variant/variant.hpp>
 
 #include <geometry_test_common.hpp>
@@ -22,7 +23,7 @@
 template <typename Geometry>
 void test_perimeter(Geometry const& geometry, long double expected_perimeter)
 {
- typename bg::default_distance_result<Geometry>::type perimeter = bg::perimeter(geometry);
+ BOOST_AUTO(perimeter, bg::perimeter(geometry));
 
 #ifdef GEOMETRY_TEST_DEBUG
     std::ostringstream out;
@@ -44,7 +45,10 @@
 {
     Geometry geometry;
     bg::read_wkt(wkt, geometry);
+ boost::variant<Geometry> v(geometry);
+
     test_perimeter(geometry, expected_perimeter);
+ test_perimeter(v, expected_perimeter);
 }
 
 template <typename Geometry>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk