diff options
Diffstat (limited to 'boost/geometry/algorithms/area.hpp')
-rw-r--r-- | boost/geometry/algorithms/area.hpp | 112 |
1 files changed, 73 insertions, 39 deletions
diff --git a/boost/geometry/algorithms/area.hpp b/boost/geometry/algorithms/area.hpp index 18aea24036..c6e237e7cc 100644 --- a/boost/geometry/algorithms/area.hpp +++ b/boost/geometry/algorithms/area.hpp @@ -3,9 +3,10 @@ // 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) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -19,7 +20,6 @@ #define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP #include <boost/concept_check.hpp> -#include <boost/mpl/if.hpp> #include <boost/range/functions.hpp> #include <boost/range/metafunctions.hpp> @@ -43,7 +43,9 @@ #include <boost/geometry/algorithms/detail/multi_sum.hpp> #include <boost/geometry/strategies/area.hpp> +#include <boost/geometry/strategies/area_result.hpp> #include <boost/geometry/strategies/default_area_result.hpp> +#include <boost/geometry/strategies/default_strategy.hpp> #include <boost/geometry/strategies/concepts/area_concept.hpp> @@ -56,6 +58,7 @@ namespace boost { namespace geometry { + #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace area { @@ -83,10 +86,10 @@ template struct ring_area { template <typename Ring, typename Strategy> - static inline typename Strategy::return_type + static inline typename area_result<Ring, Strategy>::type apply(Ring const& ring, Strategy const& strategy) { - BOOST_CONCEPT_ASSERT( (geometry::concepts::AreaStrategy<Strategy>) ); + BOOST_CONCEPT_ASSERT( (geometry::concepts::AreaStrategy<Ring, Strategy>) ); assert_dimension<Ring, 2>(); // Ignore warning (because using static method sometimes) on strategy @@ -98,7 +101,7 @@ struct ring_area if (boost::size(ring) < core_detail::closure::minimum_ring_size<Closure>::value) { - return typename Strategy::return_type(); + return typename area_result<Ring, Strategy>::type(); } typedef typename reversible_view<Ring const, Direction>::type rview_type; @@ -110,7 +113,7 @@ struct ring_area rview_type rview(ring); view_type view(rview); - typename Strategy::state_type state; + typename Strategy::template state<Ring> state; iterator_type it = boost::begin(view); iterator_type end = boost::end(view); @@ -144,9 +147,13 @@ template struct area : detail::calculate_null { template <typename Strategy> - static inline typename Strategy::return_type apply(Geometry const& geometry, Strategy const& strategy) + static inline typename area_result<Geometry, Strategy>::type + apply(Geometry const& geometry, Strategy const& strategy) { - return calculate_null::apply<typename Strategy::return_type>(geometry, strategy); + return calculate_null::apply + < + typename area_result<Geometry, Strategy>::type + >(geometry, strategy); } }; @@ -170,10 +177,11 @@ template <typename Polygon> struct area<Polygon, polygon_tag> : detail::calculate_polygon_sum { template <typename Strategy> - static inline typename Strategy::return_type apply(Polygon const& polygon, Strategy const& strategy) + static inline typename area_result<Polygon, Strategy>::type + apply(Polygon const& polygon, Strategy const& strategy) { return calculate_polygon_sum::apply< - typename Strategy::return_type, + typename area_result<Polygon, Strategy>::type, detail::area::ring_area < order_as_direction<geometry::point_order<Polygon>::value>::value, @@ -188,12 +196,12 @@ template <typename MultiGeometry> struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum { template <typename Strategy> - static inline typename Strategy::return_type + static inline typename area_result<MultiGeometry, Strategy>::type apply(MultiGeometry const& multi, Strategy const& strategy) { return multi_sum::apply < - typename Strategy::return_type, + typename area_result<MultiGeometry, Strategy>::type, area<typename boost::range_value<MultiGeometry>::type> >(multi, strategy); } @@ -204,39 +212,73 @@ struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum #endif // DOXYGEN_NO_DISPATCH -namespace resolve_variant { +namespace resolve_strategy +{ + +struct area +{ + template <typename Geometry, typename Strategy> + static inline typename area_result<Geometry, Strategy>::type + apply(Geometry const& geometry, Strategy const& strategy) + { + return dispatch::area<Geometry>::apply(geometry, strategy); + } + + template <typename Geometry> + static inline typename area_result<Geometry>::type + apply(Geometry const& geometry, default_strategy) + { + typedef typename strategy::area::services::default_strategy + < + typename cs_tag<Geometry>::type + >::type strategy_type; + + return dispatch::area<Geometry>::apply(geometry, strategy_type()); + } +}; + + +} // namespace resolve_strategy + + +namespace resolve_variant +{ template <typename Geometry> struct area { template <typename Strategy> - static inline typename Strategy::return_type apply(Geometry const& geometry, - Strategy const& strategy) + static inline typename area_result<Geometry, Strategy>::type + apply(Geometry const& geometry, Strategy const& strategy) { - return dispatch::area<Geometry>::apply(geometry, strategy); + return resolve_strategy::area::apply(geometry, strategy); } }; template <BOOST_VARIANT_ENUM_PARAMS(typename T)> struct area<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > { + typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type; + template <typename Strategy> - struct visitor: boost::static_visitor<typename Strategy::return_type> + struct visitor + : boost::static_visitor<typename area_result<variant_type, Strategy>::type> { Strategy const& m_strategy; visitor(Strategy const& strategy): m_strategy(strategy) {} template <typename Geometry> - typename Strategy::return_type operator()(Geometry const& geometry) const + typename area_result<variant_type, Strategy>::type + operator()(Geometry const& geometry) const { return area<Geometry>::apply(geometry, m_strategy); } }; template <typename Strategy> - static inline typename Strategy::return_type - apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, + static inline typename area_result<variant_type, Strategy>::type + apply(variant_type const& geometry, Strategy const& strategy) { return boost::apply_visitor(visitor<Strategy>(strategy), geometry); @@ -268,22 +310,14 @@ and Geographic as well. \qbk{[area] [area_output]} */ template <typename Geometry> -inline typename default_area_result<Geometry>::type area(Geometry const& geometry) +inline typename area_result<Geometry>::type +area(Geometry const& geometry) { concepts::check<Geometry const>(); - // TODO put this into a resolve_strategy stage - // (and take the return type from resolve_variant) - typedef typename point_type<Geometry>::type point_type; - typedef typename strategy::area::services::default_strategy - < - typename cs_tag<point_type>::type, - point_type - >::type strategy_type; - // detail::throw_on_empty_input(geometry); - return resolve_variant::area<Geometry>::apply(geometry, strategy_type()); + return resolve_variant::area<Geometry>::apply(geometry, default_strategy()); } /*! @@ -301,19 +335,19 @@ inline typename default_area_result<Geometry>::type area(Geometry const& geometr \qbk{ [include reference/algorithms/area.qbk] +[heading Available Strategies] +\* [link geometry.reference.strategies.strategy_area_cartesian Cartesian] +\* [link geometry.reference.strategies.strategy_area_spherical Spherical] +\* [link geometry.reference.strategies.strategy_area_geographic Geographic] + [heading Example] [area_with_strategy] [area_with_strategy_output] - -[heading Available Strategies] -\* [link geometry.reference.strategies.strategy_area_surveyor Surveyor (cartesian)] -\* [link geometry.reference.strategies.strategy_area_spherical Spherical] -[/link geometry.reference.strategies.strategy_area_geographic Geographic] } */ template <typename Geometry, typename Strategy> -inline typename Strategy::return_type area( - Geometry const& geometry, Strategy const& strategy) +inline typename area_result<Geometry, Strategy>::type +area(Geometry const& geometry, Strategy const& strategy) { concepts::check<Geometry const>(); |