+
+template
+<
+ typename Point, typename Geometry,
+ typename Tag2 = typename geometry::tag<Geometry>::type
+>
+struct check_within_strategy
+{
+ template <typename Strategy>
+ static inline typename Strategy::template point_in_geometry_strategy<Point, Geometry>::type
+ within(Strategy const& strategy)
+ {
+ return strategy.template get_point_in_geometry_strategy<Point, Geometry>();
+ }
+
+ template <typename Strategy>
+ static inline typename Strategy::template point_in_geometry_strategy<Point, Geometry>::type
+ covered_by(Strategy const& strategy)
+ {
+ return strategy.template get_point_in_geometry_strategy<Point, Geometry>();
+ }
+};
+
+template <typename Point, typename Geometry>
+struct check_within_strategy<Point, Geometry, box_tag>
+{
+ template <typename Strategy>
+ static inline typename Strategy::within_point_box_strategy_type
+ within(Strategy const& )
+ {
+ return typename Strategy::within_point_box_strategy_type();
+ }
+
+ template <typename Strategy>
+ static inline typename Strategy::covered_by_point_box_strategy_type
+ covered_by(Strategy const&)
+ {
+ return typename Strategy::covered_by_point_box_strategy_type();
+ }
+};
+
+
+template <overlay_type OverlayType>
+struct check_within
+{
+ template
+ <
+ typename Turn, typename Geometry0, typename Geometry1,
+ typename UmbrellaStrategy
+ >
+ static inline
+ bool apply(Turn const& turn, Geometry0 const& geometry0,
+ Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
+ {
+ typedef typename Turn::point_type point_type;
+
+ // Operations 0 and 1 have the same source index in self-turns
+ return turn.operations[0].seg_id.source_index == 0
+ ? geometry::within(turn.point, geometry1,
+ check_within_strategy<point_type, Geometry1>::within(strategy))
+ : geometry::within(turn.point, geometry0,
+ check_within_strategy<point_type, Geometry0>::within(strategy));
+ }
+
+};
+
+template <>
+struct check_within<overlay_difference>
+{
+ template
+ <
+ typename Turn, typename Geometry0, typename Geometry1,
+ typename UmbrellaStrategy
+ >
+ static inline
+ bool apply(Turn const& turn, Geometry0 const& geometry0,
+ Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
+ {
+ typedef typename Turn::point_type point_type;
+
+ // difference = intersection(a, reverse(b))
+ // therefore we should reverse the meaning of within for geometry1
+ return turn.operations[0].seg_id.source_index == 0
+ ? ! geometry::covered_by(turn.point, geometry1,
+ check_within_strategy<point_type, Geometry1>::covered_by(strategy))
+ : geometry::within(turn.point, geometry0,
+ check_within_strategy<point_type, Geometry0>::within(strategy));
+ }
+};
+