1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2014-2015, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 7 // Licensed under the Boost Software License version 1.0. 8 // http://www.boost.org/users/license.html 9 10 #ifndef BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP 11 #define BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP 12 13 #include <boost/mpl/always.hpp> 14 #include <boost/mpl/bool.hpp> 15 #include <boost/mpl/vector.hpp> 16 17 #include <boost/variant/variant_fwd.hpp> 18 19 #include <boost/geometry/core/point_type.hpp> 20 21 #include <boost/geometry/strategies/default_strategy.hpp> 22 #include <boost/geometry/strategies/distance.hpp> 23 24 #include <boost/geometry/util/compress_variant.hpp> 25 #include <boost/geometry/util/transform_variant.hpp> 26 #include <boost/geometry/util/combine_if.hpp> 27 28 #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp> 29 30 31 namespace boost { namespace geometry 32 { 33 34 namespace resolve_strategy 35 { 36 37 template <typename Geometry1, typename Geometry2, typename Strategy> 38 struct comparable_distance_result 39 : strategy::distance::services::return_type 40 < 41 typename strategy::distance::services::comparable_type 42 < 43 Strategy 44 >::type, 45 typename point_type<Geometry1>::type, 46 typename point_type<Geometry2>::type 47 > 48 {}; 49 50 template <typename Geometry1, typename Geometry2> 51 struct comparable_distance_result<Geometry1, Geometry2, default_strategy> 52 : comparable_distance_result 53 < 54 Geometry1, 55 Geometry2, 56 typename detail::distance::default_strategy 57 < 58 Geometry1, Geometry2 59 >::type 60 > 61 {}; 62 63 } // namespace resolve_strategy 64 65 66 namespace resolve_variant 67 { 68 69 template <typename Geometry1, typename Geometry2, typename Strategy> 70 struct comparable_distance_result 71 : resolve_strategy::comparable_distance_result 72 < 73 Geometry1, 74 Geometry2, 75 Strategy 76 > 77 {}; 78 79 80 template 81 < 82 typename Geometry1, 83 BOOST_VARIANT_ENUM_PARAMS(typename T), 84 typename Strategy 85 > 86 struct comparable_distance_result 87 < 88 Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy 89 > 90 { 91 // A set of all variant type combinations that are compatible and 92 // implemented 93 typedef typename util::combine_if< 94 typename boost::mpl::vector1<Geometry1>, 95 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, 96 boost::mpl::always<boost::mpl::true_> 97 >::type possible_input_types; 98 99 // The (possibly variant) result type resulting from these combinations 100 typedef typename compress_variant< 101 typename transform_variant< 102 possible_input_types, 103 resolve_strategy::comparable_distance_result< 104 boost::mpl::first<boost::mpl::_>, 105 boost::mpl::second<boost::mpl::_>, 106 Strategy 107 >, 108 boost::mpl::back_inserter<boost::mpl::vector0<> > 109 >::type 110 >::type type; 111 }; 112 113 114 // Distance arguments are commutative 115 template 116 < 117 BOOST_VARIANT_ENUM_PARAMS(typename T), 118 typename Geometry2, 119 typename Strategy 120 > 121 struct comparable_distance_result 122 < 123 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, 124 Geometry2, 125 Strategy 126 > : public comparable_distance_result 127 < 128 Geometry2, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy 129 > 130 {}; 131 132 133 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy> 134 struct comparable_distance_result 135 < 136 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, 137 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, 138 Strategy 139 > 140 { 141 // A set of all variant type combinations that are compatible and 142 // implemented 143 typedef typename util::combine_if 144 < 145 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, 146 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, 147 boost::mpl::always<boost::mpl::true_> 148 >::type possible_input_types; 149 150 // The (possibly variant) result type resulting from these combinations 151 typedef typename compress_variant< 152 typename transform_variant< 153 possible_input_types, 154 resolve_strategy::comparable_distance_result< 155 boost::mpl::first<boost::mpl::_>, 156 boost::mpl::second<boost::mpl::_>, 157 Strategy 158 >, 159 boost::mpl::back_inserter<boost::mpl::vector0<> > 160 >::type 161 >::type type; 162 }; 163 164 } // namespace resolve_variant 165 166 167 168 169 170 /*! 171 \brief Meta-function defining return type of comparable_distance function 172 \ingroup distance 173 */ 174 template 175 < 176 typename Geometry1, 177 typename Geometry2 = Geometry1, 178 typename Strategy = void 179 > 180 struct comparable_distance_result 181 : resolve_variant::comparable_distance_result 182 < 183 Geometry1, Geometry2, Strategy 184 > 185 {}; 186 187 template <typename Geometry1, typename Geometry2> 188 struct comparable_distance_result<Geometry1, Geometry2, void> 189 : comparable_distance_result<Geometry1, Geometry2, default_strategy> 190 {}; 191 192 193 }} // namespace boost::geometry 194 195 196 #endif // BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP 197