1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2014. 8 // Modifications copyright (c) 2014, Oracle and/or its affiliates. 9 10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 11 12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 14 15 // Use, modification and distribution is subject to the Boost Software License, 16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 17 // http://www.boost.org/LICENSE_1_0.txt) 18 19 #ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP 20 #define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP 21 22 #include <vector> 23 #include <iterator> 24 25 #include <boost/concept_check.hpp> 26 #include <boost/core/ignore_unused.hpp> 27 #include <boost/mpl/assert.hpp> 28 #include <boost/type_traits/is_same.hpp> 29 30 #include <boost/geometry/util/parameter_type_of.hpp> 31 32 #include <boost/geometry/geometries/concepts/point_concept.hpp> 33 #include <boost/geometry/geometries/segment.hpp> 34 #include <boost/geometry/geometries/point.hpp> 35 36 #include <boost/geometry/strategies/tags.hpp> 37 38 39 namespace boost { namespace geometry { namespace concepts 40 { 41 42 43 /*! 44 \brief Checks strategy for point-point or point-box or box-box distance 45 \ingroup distance 46 */ 47 template <typename Strategy, typename Point1, typename Point2> 48 struct PointDistanceStrategy 49 { 50 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS 51 private : 52 53 struct checker 54 { 55 template <typename ApplyMethod> applyboost::geometry::concepts::PointDistanceStrategy::checker56 static void apply(ApplyMethod) 57 { 58 // 1: inspect and define both arguments of apply 59 typedef typename parameter_type_of 60 < 61 ApplyMethod, 0 62 >::type ptype1; 63 64 typedef typename parameter_type_of 65 < 66 ApplyMethod, 1 67 >::type ptype2; 68 69 // 2) must define meta-function "return_type" 70 typedef typename strategy::distance::services::return_type 71 < 72 Strategy, ptype1, ptype2 73 >::type rtype; 74 75 // 3) must define meta-function "comparable_type" 76 typedef typename strategy::distance::services::comparable_type 77 < 78 Strategy 79 >::type ctype; 80 81 // 4) must define meta-function "tag" 82 typedef typename strategy::distance::services::tag 83 < 84 Strategy 85 >::type tag; 86 87 static const bool is_correct_strategy_tag = 88 boost::is_same<tag, strategy_tag_distance_point_point>::value 89 || boost::is_same<tag, strategy_tag_distance_point_box>::value 90 || boost::is_same<tag, strategy_tag_distance_box_box>::value; 91 92 BOOST_MPL_ASSERT_MSG 93 ((is_correct_strategy_tag), 94 INCORRECT_STRATEGY_TAG, 95 (types<tag>)); 96 97 // 5) must implement apply with arguments 98 Strategy* str = 0; 99 ptype1 *p1 = 0; 100 ptype2 *p2 = 0; 101 rtype r = str->apply(*p1, *p2); 102 103 // 6) must define (meta)struct "get_comparable" with apply 104 ctype c = strategy::distance::services::get_comparable 105 < 106 Strategy 107 >::apply(*str); 108 109 // 7) must define (meta)struct "result_from_distance" with apply 110 r = strategy::distance::services::result_from_distance 111 < 112 Strategy, 113 ptype1, ptype2 114 >::apply(*str, 1.0); 115 116 boost::ignore_unused<tag>(); 117 boost::ignore_unused(str, c, r); 118 } 119 }; 120 121 122 123 public : BOOST_CONCEPT_USAGEboost::geometry::concepts::PointDistanceStrategy124 BOOST_CONCEPT_USAGE(PointDistanceStrategy) 125 { 126 checker::apply(&Strategy::template apply<Point1, Point2>); 127 } 128 #endif 129 }; 130 131 132 /*! 133 \brief Checks strategy for point-segment distance 134 \ingroup strategy_concepts 135 */ 136 template <typename Strategy, typename Point, typename PointOfSegment> 137 struct PointSegmentDistanceStrategy 138 { 139 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS 140 private : 141 142 struct checker 143 { 144 template <typename ApplyMethod> applyboost::geometry::concepts::PointSegmentDistanceStrategy::checker145 static void apply(ApplyMethod) 146 { 147 // 1) inspect and define both arguments of apply 148 typedef typename parameter_type_of 149 < 150 ApplyMethod, 0 151 >::type ptype; 152 153 typedef typename parameter_type_of 154 < 155 ApplyMethod, 1 156 >::type sptype; 157 158 namespace services = strategy::distance::services; 159 // 2) must define meta-function "tag" 160 typedef typename services::tag<Strategy>::type tag; 161 162 BOOST_MPL_ASSERT_MSG 163 ((boost::is_same 164 < 165 tag, strategy_tag_distance_point_segment 166 >::value), 167 INCORRECT_STRATEGY_TAG, 168 (types<tag>)); 169 170 // 3) must define meta-function "return_type" 171 typedef typename services::return_type 172 < 173 Strategy, ptype, sptype 174 >::type rtype; 175 176 // 4) must define meta-function "comparable_type" 177 typedef typename services::comparable_type<Strategy>::type ctype; 178 179 // 5) must implement apply with arguments 180 Strategy *str = 0; 181 ptype *p = 0; 182 sptype *sp1 = 0; 183 sptype *sp2 = 0; 184 185 rtype r = str->apply(*p, *sp1, *sp2); 186 187 // 6) must define (meta-)struct "get_comparable" with apply 188 ctype cstrategy = services::get_comparable<Strategy>::apply(*str); 189 190 // 7) must define (meta-)struct "result_from_distance" with apply 191 r = services::result_from_distance 192 < 193 Strategy, ptype, sptype 194 >::apply(*str, rtype(1.0)); 195 196 boost::ignore_unused(str, r, cstrategy); 197 } 198 }; 199 200 public : BOOST_CONCEPT_USAGEboost::geometry::concepts::PointSegmentDistanceStrategy201 BOOST_CONCEPT_USAGE(PointSegmentDistanceStrategy) 202 { 203 checker::apply(&Strategy::template apply<Point, PointOfSegment>); 204 } 205 #endif 206 }; 207 208 209 }}} // namespace boost::geometry::concepts 210 211 212 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP 213