]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | ||
5 | // Use, modification and distribution is subject to the Boost Software License, | |
6 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | #ifndef BOOST_GEOMETRY_POLICIES_COMPARE_HPP | |
10 | #define BOOST_GEOMETRY_POLICIES_COMPARE_HPP | |
11 | ||
12 | ||
13 | #include <cstddef> | |
14 | ||
15 | #include <boost/geometry/strategies/compare.hpp> | |
16 | #include <boost/geometry/util/math.hpp> | |
17 | ||
18 | ||
19 | namespace boost { namespace geometry | |
20 | { | |
21 | ||
22 | ||
23 | #ifndef DOXYGEN_NO_DETAIL | |
24 | namespace detail { namespace compare | |
25 | { | |
26 | ||
27 | ||
28 | template | |
29 | < | |
30 | int Direction, | |
31 | typename Point, | |
32 | typename Strategy, | |
33 | std::size_t Dimension, | |
34 | std::size_t DimensionCount | |
35 | > | |
36 | struct compare_loop | |
37 | { | |
38 | typedef typename strategy::compare::detail::select_strategy | |
39 | < | |
40 | Strategy, Direction, Point, Dimension | |
41 | >::type compare_type; | |
42 | ||
43 | typedef typename geometry::coordinate_type<Point>::type coordinate_type; | |
44 | ||
45 | static inline bool apply(Point const& left, Point const& right) | |
46 | { | |
47 | coordinate_type const& cleft = geometry::get<Dimension>(left); | |
48 | coordinate_type const& cright = geometry::get<Dimension>(right); | |
49 | ||
50 | if (geometry::math::equals(cleft, cright)) | |
51 | { | |
52 | return compare_loop | |
53 | < | |
54 | Direction, Point, Strategy, | |
55 | Dimension + 1, DimensionCount | |
56 | >::apply(left, right); | |
57 | } | |
58 | else | |
59 | { | |
60 | compare_type compare; | |
61 | return compare(cleft, cright); | |
62 | } | |
63 | } | |
64 | }; | |
65 | ||
66 | template | |
67 | < | |
68 | int Direction, | |
69 | typename Point, | |
70 | typename Strategy, | |
71 | std::size_t DimensionCount | |
72 | > | |
73 | struct compare_loop<Direction, Point, Strategy, DimensionCount, DimensionCount> | |
74 | { | |
75 | static inline bool apply(Point const&, Point const&) | |
76 | { | |
77 | // On coming here, points are equal. Return true if | |
78 | // direction = 0 (equal), false if -1/1 (greater/less) | |
79 | return Direction == 0; | |
80 | } | |
81 | }; | |
82 | ||
83 | ||
84 | template <int Direction, typename Point, typename Strategy> | |
85 | struct compare_in_all_dimensions | |
86 | { | |
87 | inline bool operator()(Point const& left, Point const& right) const | |
88 | { | |
89 | return detail::compare::compare_loop | |
90 | < | |
91 | Direction, Point, Strategy, | |
92 | 0, geometry::dimension<Point>::type::value | |
93 | >::apply(left, right); | |
94 | } | |
95 | }; | |
96 | ||
97 | ||
98 | template <typename Point, typename Strategy, std::size_t Dimension> | |
99 | class compare_in_one_dimension | |
100 | { | |
101 | Strategy compare; | |
102 | ||
103 | public : | |
104 | inline bool operator()(Point const& left, Point const& right) const | |
105 | { | |
106 | typedef typename geometry::coordinate_type<Point>::type coordinate_type; | |
107 | ||
108 | coordinate_type const& cleft = get<Dimension>(left); | |
109 | coordinate_type const& cright = get<Dimension>(right); | |
110 | return compare(cleft, cright); | |
111 | } | |
112 | }; | |
113 | ||
114 | }} // namespace detail::compare | |
115 | ||
116 | #endif | |
117 | ||
118 | #ifndef DOXYGEN_NO_DISPATCH | |
119 | namespace dispatch | |
120 | { | |
121 | ||
122 | template | |
123 | < | |
124 | int Direction, | |
125 | typename Point, | |
126 | typename Strategy, | |
127 | int Dimension | |
128 | > | |
129 | struct compare_geometries | |
130 | : detail::compare::compare_in_one_dimension | |
131 | < | |
132 | Point, | |
133 | typename strategy::compare::detail::select_strategy | |
134 | < | |
135 | Strategy, Direction, Point, Dimension | |
136 | >::type, | |
137 | Dimension | |
138 | > | |
139 | {}; | |
140 | ||
141 | ||
142 | // Specialization with -1: compare in all dimensions | |
143 | template <int Direction, typename Point, typename Strategy> | |
144 | struct compare_geometries<Direction, Point, Strategy, -1> | |
145 | : detail::compare::compare_in_all_dimensions<Direction, Point, Strategy> | |
146 | {}; | |
147 | ||
148 | ||
149 | ||
150 | } // namespace dispatch | |
151 | #endif // DOXYGEN_NO_DISPATCH | |
152 | ||
153 | ||
154 | /*! | |
155 | \brief Less functor, to sort points in ascending order. | |
156 | \ingroup compare | |
157 | \details This functor compares points and orders them on x, | |
158 | then on y, then on z coordinate. | |
159 | \tparam Geometry the geometry | |
160 | \tparam Dimension the dimension to sort on, defaults to -1, | |
161 | indicating ALL dimensions. That's to say, first on x, | |
162 | on equal x-es then on y, etc. | |
163 | If a dimension is specified, only that dimension is considered | |
164 | \tparam Strategy underlying coordinate comparing functor, | |
165 | defaults to the default comparison strategies | |
166 | related to the point coordinate system. If specified, the specified | |
167 | strategy is used. This can e.g. be std::less<double>. | |
168 | */ | |
169 | template | |
170 | < | |
171 | typename Point, | |
172 | int Dimension = -1, | |
173 | typename Strategy = strategy::compare::default_strategy | |
174 | > | |
175 | struct less | |
176 | : dispatch::compare_geometries | |
177 | < | |
178 | 1, // indicates ascending | |
179 | Point, | |
180 | Strategy, | |
181 | Dimension | |
182 | > | |
183 | { | |
184 | typedef Point first_argument_type; | |
185 | typedef Point second_argument_type; | |
186 | typedef bool result_type; | |
187 | }; | |
188 | ||
189 | ||
190 | /*! | |
191 | \brief Greater functor | |
192 | \ingroup compare | |
193 | \details Can be used to sort points in reverse order | |
194 | \see Less functor | |
195 | */ | |
196 | template | |
197 | < | |
198 | typename Point, | |
199 | int Dimension = -1, | |
200 | typename Strategy = strategy::compare::default_strategy | |
201 | > | |
202 | struct greater | |
203 | : dispatch::compare_geometries | |
204 | < | |
205 | -1, // indicates descending | |
206 | Point, | |
207 | Strategy, | |
208 | Dimension | |
209 | > | |
210 | {}; | |
211 | ||
212 | ||
213 | /*! | |
214 | \brief Equal To functor, to compare if points are equal | |
215 | \ingroup compare | |
216 | \tparam Geometry the geometry | |
217 | \tparam Dimension the dimension to compare on, defaults to -1, | |
218 | indicating ALL dimensions. | |
219 | If a dimension is specified, only that dimension is considered | |
220 | \tparam Strategy underlying coordinate comparing functor | |
221 | */ | |
222 | template | |
223 | < | |
224 | typename Point, | |
225 | int Dimension = -1, | |
226 | typename Strategy = strategy::compare::default_strategy | |
227 | > | |
228 | struct equal_to | |
229 | : dispatch::compare_geometries | |
230 | < | |
231 | 0, | |
232 | Point, | |
233 | Strategy, | |
234 | Dimension | |
235 | > | |
236 | {}; | |
237 | ||
238 | ||
239 | }} // namespace boost::geometry | |
240 | ||
241 | ||
242 | #endif // BOOST_GEOMETRY_POLICIES_COMPARE_HPP |