+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_rescale_policy
+{
+
+
+// get envelope strategy compatible with relate strategy based on geometry tag
+// and strategy cs_tag
+template
+<
+ typename Geometry,
+ typename Strategy,
+ typename Tag = typename geometry::tag<Geometry>::type,
+ typename CSTag = typename Strategy::cs_tag
+>
+struct get_envelope_strategy
+{
+ typedef typename Strategy::envelope_strategy_type type;
+
+ static inline type apply(Strategy const& strategy)
+ {
+ return strategy.get_envelope_strategy();
+ }
+};
+
+template <typename Geometry, typename Strategy, typename CSTag>
+struct get_envelope_strategy<Geometry, Strategy, box_tag, CSTag>
+{
+ typedef typename Strategy::envelope_box_strategy_type type;
+
+ static inline type apply(Strategy const& )
+ {
+ return type();
+ }
+};
+
+// NOTE: within::xxx_point_point shouldn't have a getter for envelope strategy
+// so dispatch by CStag. In the future strategies should probably be redesigned.
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, point_tag, cartesian_tag>
+{
+ typedef strategy::envelope::cartesian_point type;
+
+ static inline type apply(Strategy const& )
+ {
+ return type();
+ }
+};
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, point_tag, spherical_tag>
+{
+ typedef strategy::envelope::spherical_point type;
+
+ static inline type apply(Strategy const& )
+ {
+ return type();
+ }
+};
+
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, multi_point_tag, cartesian_tag>
+{
+ typedef strategy::envelope::cartesian_point type;
+
+ static inline type apply(Strategy const& )
+ {
+ return type();
+ }
+};
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, multi_point_tag, spherical_tag>
+{
+ typedef strategy::envelope::spherical_point type;
+
+ static inline type apply(Strategy const& )
+ {
+ return type();
+ }
+};
+
+
+// utility for backward-compatibility either treating the argument as geometry
+// or envelope strategy for get_rescale_policy
+template
+<
+ typename Geometry2OrStrategy,
+ typename Tag = typename geometry::tag<Geometry2OrStrategy>::type
+>
+struct get_rescale_policy_geometry_or_strategy
+{
+ template <typename Policy, typename Geometry>
+ static inline Policy apply(Geometry const& geometry, Geometry2OrStrategy const& geometry2)
+ {
+ typename geometry::strategy::envelope::services::default_strategy
+ <
+ typename geometry::tag<Geometry>::type,
+ typename geometry::cs_tag<Geometry>::type
+ >::type strategy1;
+ typename geometry::strategy::envelope::services::default_strategy
+ <
+ typename geometry::tag<Geometry2OrStrategy>::type,
+ typename geometry::cs_tag<Geometry2OrStrategy>::type
+ >::type strategy2;
+
+ return detail::get_rescale_policy::get_rescale_policy
+ <
+ Policy
+ >::apply(geometry, geometry2, strategy1, strategy2);
+ }
+};
+
+template <typename Strategy>
+struct get_rescale_policy_geometry_or_strategy<Strategy, void>
+{
+ template <typename Policy, typename Geometry>
+ static inline Policy apply(Geometry const& geometry, Strategy const& strategy)
+ {
+ return detail::get_rescale_policy::get_rescale_policy
+ <
+ Policy
+ >::apply(geometry,
+ get_envelope_strategy
+ <
+ Geometry, Strategy
+ >::apply(strategy));
+ }
+};
+
+
+}} // namespace detail::get_rescale_policy
+#endif // DOXYGEN_NO_DETAIL
+
+