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