1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. 6 // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. 7 // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. 8 9 // This file was modified by Oracle on 2014, 2015. 10 // Modifications copyright (c) 2014-2015, Oracle and/or its affiliates. 11 12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 13 14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 16 17 // Use, modification and distribution is subject to the Boost Software License, 18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 19 // http://www.boost.org/LICENSE_1_0.txt) 20 21 #ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP 22 #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP 23 24 #include <boost/mpl/always.hpp> 25 #include <boost/mpl/bool.hpp> 26 #include <boost/mpl/vector.hpp> 27 28 #include <boost/variant/variant_fwd.hpp> 29 30 #include <boost/geometry/core/point_type.hpp> 31 32 #include <boost/geometry/strategies/default_strategy.hpp> 33 #include <boost/geometry/strategies/distance.hpp> 34 35 #include <boost/geometry/util/compress_variant.hpp> 36 #include <boost/geometry/util/transform_variant.hpp> 37 #include <boost/geometry/util/combine_if.hpp> 38 39 #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp> 40 41 42 namespace boost { namespace geometry 43 { 44 45 46 namespace resolve_strategy 47 { 48 49 template <typename Geometry1, typename Geometry2, typename Strategy> 50 struct distance_result 51 : strategy::distance::services::return_type 52 < 53 Strategy, 54 typename point_type<Geometry1>::type, 55 typename point_type<Geometry2>::type 56 > 57 {}; 58 59 template <typename Geometry1, typename Geometry2> 60 struct distance_result<Geometry1, Geometry2, default_strategy> 61 : distance_result 62 < 63 Geometry1, 64 Geometry2, 65 typename detail::distance::default_strategy 66 < 67 Geometry1, Geometry2 68 >::type 69 > 70 {}; 71 72 } // namespace resolve_strategy 73 74 75 namespace resolve_variant 76 { 77 78 template <typename Geometry1, typename Geometry2, typename Strategy> 79 struct distance_result 80 : resolve_strategy::distance_result 81 < 82 Geometry1, 83 Geometry2, 84 Strategy 85 > 86 {}; 87 88 89 template 90 < 91 typename Geometry1, 92 BOOST_VARIANT_ENUM_PARAMS(typename T), 93 typename Strategy 94 > 95 struct distance_result 96 < 97 Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy 98 > 99 { 100 // A set of all variant type combinations that are compatible and 101 // implemented 102 typedef typename util::combine_if< 103 typename boost::mpl::vector1<Geometry1>, 104 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, 105 // Here we want should remove most of the combinations that 106 // are not valid, mostly to limit the size of the resulting MPL set. 107 // But is_implementedn is not ready for prime time 108 // 109 // util::is_implemented2<boost::mpl::_1, boost::mpl::_2, dispatch::distance<boost::mpl::_1, boost::mpl::_2> > 110 boost::mpl::always<boost::mpl::true_> 111 >::type possible_input_types; 112 113 // The (possibly variant) result type resulting from these combinations 114 typedef typename compress_variant< 115 typename transform_variant< 116 possible_input_types, 117 resolve_strategy::distance_result< 118 boost::mpl::first<boost::mpl::_>, 119 boost::mpl::second<boost::mpl::_>, 120 Strategy 121 >, 122 boost::mpl::back_inserter<boost::mpl::vector0<> > 123 >::type 124 >::type type; 125 }; 126 127 128 // Distance arguments are commutative 129 template 130 < 131 BOOST_VARIANT_ENUM_PARAMS(typename T), 132 typename Geometry2, 133 typename Strategy 134 > 135 struct distance_result 136 < 137 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, 138 Geometry2, 139 Strategy 140 > : public distance_result 141 < 142 Geometry2, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy 143 > 144 {}; 145 146 147 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy> 148 struct distance_result 149 < 150 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, 151 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, 152 Strategy 153 > 154 { 155 // A set of all variant type combinations that are compatible and 156 // implemented 157 typedef typename util::combine_if 158 < 159 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, 160 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, 161 // Here we want to try to remove most of the combinations 162 // that are not valid, mostly to limit the size of the 163 // resulting MPL vector. 164 // But is_implemented is not ready for prime time 165 // 166 // util::is_implemented2<boost::mpl::_1, boost::mpl::_2, dispatch::distance<boost::mpl::_1, boost::mpl::_2> > 167 boost::mpl::always<boost::mpl::true_> 168 >::type possible_input_types; 169 170 // The (possibly variant) result type resulting from these combinations 171 typedef typename compress_variant< 172 typename transform_variant< 173 possible_input_types, 174 resolve_strategy::distance_result< 175 boost::mpl::first<boost::mpl::_>, 176 boost::mpl::second<boost::mpl::_>, 177 Strategy 178 >, 179 boost::mpl::back_inserter<boost::mpl::vector0<> > 180 >::type 181 >::type type; 182 }; 183 184 } // namespace resolve_variant 185 186 187 /*! 188 \brief Meta-function defining return type of distance function 189 \ingroup distance 190 \note The strategy defines the return-type (so this situation is different 191 from length, where distance is sqr/sqrt, but length always squared) 192 */ 193 template 194 < 195 typename Geometry1, 196 typename Geometry2 = Geometry1, 197 typename Strategy = void 198 > 199 struct distance_result 200 : resolve_variant::distance_result<Geometry1, Geometry2, Strategy> 201 {}; 202 203 204 template <typename Geometry1, typename Geometry2> 205 struct distance_result<Geometry1, Geometry2, void> 206 : distance_result<Geometry1, Geometry2, default_strategy> 207 {}; 208 209 210 }} // namespace boost::geometry 211 212 213 #endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP 214