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