]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry Index |
2 | // | |
92f5a8d4 | 3 | // Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland. |
7c673cae | 4 | // |
20effc67 TL |
5 | // This file was modified by Oracle on 2020. |
6 | // Modifications copyright (c) 2020 Oracle and/or its affiliates. | |
7 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
8 | // | |
7c673cae FG |
9 | // Use, modification and distribution is subject to the Boost Software License, |
10 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
11 | // http://www.boost.org/LICENSE_1_0.txt) | |
12 | ||
13 | #ifndef BOOST_GEOMETRY_INDEX_INDEXABLE_HPP | |
14 | #define BOOST_GEOMETRY_INDEX_INDEXABLE_HPP | |
15 | ||
b32b8144 | 16 | #include <boost/tuple/tuple.hpp> |
20effc67 TL |
17 | |
18 | #include <boost/geometry/core/static_assert.hpp> | |
7c673cae FG |
19 | |
20 | #include <boost/geometry/index/detail/is_indexable.hpp> | |
21 | ||
20effc67 | 22 | #include <boost/geometry/util/type_traits.hpp> |
7c673cae | 23 | |
20effc67 TL |
24 | namespace boost { namespace geometry { namespace index { namespace detail |
25 | { | |
92f5a8d4 TL |
26 | |
27 | template <typename From, typename To> | |
28 | struct is_referencable | |
20effc67 | 29 | : std::is_same |
92f5a8d4 | 30 | < |
20effc67 TL |
31 | typename util::remove_cref<From>::type, |
32 | typename util::remove_cref<To>::type | |
92f5a8d4 TL |
33 | > |
34 | {}; | |
35 | ||
36 | template <typename Indexable, typename V> | |
37 | inline Indexable const& indexable_prevent_any_type(V const& ) | |
38 | { | |
20effc67 | 39 | BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Unexpected type.", V); |
92f5a8d4 TL |
40 | return Indexable(); |
41 | } | |
42 | ||
7c673cae FG |
43 | /*! |
44 | \brief The function object extracting Indexable from Value. | |
45 | ||
46 | It translates Value object to Indexable object. The default version handles Values which are Indexables. | |
47 | This template is also specialized for std::pair<Indexable, T2>, boost::tuple<Indexable, ...> | |
48 | and std::tuple<Indexable, ...>. | |
49 | ||
50 | \tparam Value The Value type which may be translated directly to the Indexable. | |
51 | \tparam IsIndexable If true, the const reference to Value is returned. | |
52 | */ | |
53 | template <typename Value, bool IsIndexable = is_indexable<Value>::value> | |
54 | struct indexable | |
55 | { | |
20effc67 | 56 | BOOST_GEOMETRY_STATIC_ASSERT( |
7c673cae | 57 | (detail::is_indexable<Value>::value), |
20effc67 TL |
58 | "Value has to be an Indexable.", |
59 | Value); | |
7c673cae FG |
60 | |
61 | /*! \brief The type of result returned by function object. */ | |
62 | typedef Value const& result_type; | |
63 | ||
64 | /*! | |
65 | \brief Return indexable extracted from the value. | |
66 | ||
67 | \param v The value. | |
68 | \return The indexable. | |
69 | */ | |
70 | inline result_type operator()(Value const& v) const | |
71 | { | |
72 | return v; | |
73 | } | |
92f5a8d4 TL |
74 | |
75 | /*! | |
76 | \brief Prevent reference to temporary for types convertible to Value. | |
77 | */ | |
78 | template <typename V> | |
79 | inline result_type operator()(V const& v) const | |
80 | { | |
81 | return indexable_prevent_any_type<Value>(v); | |
82 | } | |
7c673cae FG |
83 | }; |
84 | ||
85 | /*! | |
86 | \brief The function object extracting Indexable from Value. | |
87 | ||
88 | This specialization translates from std::pair<Indexable, T2>. | |
89 | ||
90 | \tparam Indexable The Indexable type. | |
92f5a8d4 | 91 | \tparam Second The second type. |
7c673cae | 92 | */ |
92f5a8d4 TL |
93 | template <typename Indexable, typename Second> |
94 | struct indexable<std::pair<Indexable, Second>, false> | |
7c673cae | 95 | { |
92f5a8d4 TL |
96 | typedef std::pair<Indexable, Second> value_type; |
97 | ||
20effc67 | 98 | BOOST_GEOMETRY_STATIC_ASSERT( |
7c673cae | 99 | (detail::is_indexable<Indexable>::value), |
20effc67 TL |
100 | "The first type of std::pair has to be an Indexable.", |
101 | Indexable); | |
7c673cae FG |
102 | |
103 | /*! \brief The type of result returned by function object. */ | |
104 | typedef Indexable const& result_type; | |
105 | ||
106 | /*! | |
107 | \brief Return indexable extracted from the value. | |
108 | ||
109 | \param v The value. | |
110 | \return The indexable. | |
111 | */ | |
92f5a8d4 | 112 | inline result_type operator()(value_type const& v) const |
7c673cae FG |
113 | { |
114 | return v.first; | |
115 | } | |
92f5a8d4 TL |
116 | |
117 | /*! | |
118 | \brief Return indexable extracted from compatible type different than value_type. | |
119 | ||
120 | \param v The value. | |
121 | \return The indexable. | |
122 | */ | |
123 | template <typename I, typename S> | |
124 | inline result_type operator()(std::pair<I, S> const& v) const | |
125 | { | |
20effc67 | 126 | BOOST_GEOMETRY_STATIC_ASSERT( |
92f5a8d4 | 127 | (is_referencable<I, result_type>::value), |
20effc67 TL |
128 | "Unexpected type.", |
129 | std::pair<I, S>); | |
92f5a8d4 TL |
130 | return v.first; |
131 | } | |
132 | ||
133 | /*! | |
134 | \brief Prevent reference to temporary for types convertible to Value. | |
135 | */ | |
136 | template <typename V> | |
137 | inline result_type operator()(V const& v) const | |
138 | { | |
139 | return indexable_prevent_any_type<Indexable>(v); | |
140 | } | |
7c673cae FG |
141 | }; |
142 | ||
143 | /*! | |
144 | \brief The function object extracting Indexable from Value. | |
145 | ||
92f5a8d4 TL |
146 | This specialization translates from boost::tuple<Indexable, ...> |
147 | or boost::tuples::cons<Indexable, ...>. | |
7c673cae | 148 | |
92f5a8d4 | 149 | \tparam Value The Value type. |
7c673cae FG |
150 | \tparam Indexable The Indexable type. |
151 | */ | |
92f5a8d4 TL |
152 | template <typename Value, typename Indexable> |
153 | struct indexable_boost_tuple | |
7c673cae | 154 | { |
92f5a8d4 | 155 | typedef Value value_type; |
7c673cae | 156 | |
20effc67 | 157 | BOOST_GEOMETRY_STATIC_ASSERT( |
7c673cae | 158 | (detail::is_indexable<Indexable>::value), |
20effc67 TL |
159 | "The first type of boost::tuple has to be an Indexable.", |
160 | Indexable); | |
7c673cae FG |
161 | |
162 | /*! \brief The type of result returned by function object. */ | |
163 | typedef Indexable const& result_type; | |
164 | ||
165 | /*! | |
166 | \brief Return indexable extracted from the value. | |
167 | ||
168 | \param v The value. | |
169 | \return The indexable. | |
170 | */ | |
171 | inline result_type operator()(value_type const& v) const | |
172 | { | |
173 | return boost::get<0>(v); | |
174 | } | |
92f5a8d4 TL |
175 | |
176 | /*! | |
177 | \brief Return indexable extracted from compatible type different than value_type. | |
178 | ||
179 | \param v The value. | |
180 | \return The indexable. | |
181 | */ | |
182 | template <typename I, typename U1, typename U2, typename U3, typename U4, | |
183 | typename U5, typename U6, typename U7, typename U8, typename U9> | |
184 | inline result_type operator()(boost::tuple<I, U1, U2, U3, U4, U5, U6, U7, U8, U9> const& v) const | |
185 | { | |
20effc67 | 186 | BOOST_GEOMETRY_STATIC_ASSERT( |
92f5a8d4 | 187 | (is_referencable<I, result_type>::value), |
20effc67 TL |
188 | "Unexpected type.", |
189 | boost::tuple<I, U1, U2, U3, U4, U5, U6, U7, U8, U9>); | |
92f5a8d4 TL |
190 | return boost::get<0>(v); |
191 | } | |
192 | ||
193 | /*! | |
194 | \brief Return indexable extracted from compatible type different than value_type. | |
195 | ||
196 | \param v The value. | |
197 | \return The indexable. | |
198 | */ | |
199 | template <typename I, typename T> | |
200 | inline result_type operator()(boost::tuples::cons<I, T> const& v) const | |
201 | { | |
20effc67 | 202 | BOOST_GEOMETRY_STATIC_ASSERT( |
92f5a8d4 | 203 | (is_referencable<I, result_type>::value), |
20effc67 TL |
204 | "Unexpected type.", |
205 | boost::tuples::cons<I, T>); | |
92f5a8d4 TL |
206 | return boost::get<0>(v); |
207 | } | |
208 | ||
209 | /*! | |
210 | \brief Prevent reference to temporary for types convertible to Value. | |
211 | */ | |
212 | template <typename V> | |
213 | inline result_type operator()(V const& v) const | |
214 | { | |
215 | return indexable_prevent_any_type<Indexable>(v); | |
216 | } | |
7c673cae FG |
217 | }; |
218 | ||
92f5a8d4 TL |
219 | /*! |
220 | \brief The function object extracting Indexable from Value. | |
221 | ||
222 | This specialization translates from boost::tuple<Indexable, ...>. | |
223 | ||
224 | \tparam Indexable The Indexable type. | |
225 | */ | |
226 | template <typename Indexable, typename T1, typename T2, typename T3, typename T4, | |
227 | typename T5, typename T6, typename T7, typename T8, typename T9> | |
228 | struct indexable<boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false> | |
229 | : indexable_boost_tuple | |
230 | < | |
231 | boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>, | |
232 | Indexable | |
233 | > | |
234 | {}; | |
235 | ||
236 | /*! | |
237 | \brief The function object extracting Indexable from Value. | |
238 | ||
239 | This specialization translates from boost::tuples::cons<Indexable, ...>. | |
240 | ||
241 | \tparam Indexable The Indexable type. | |
242 | */ | |
243 | template <typename Indexable, typename Tail> | |
244 | struct indexable<boost::tuples::cons<Indexable, Tail>, false> | |
245 | : indexable_boost_tuple | |
246 | < | |
247 | boost::tuples::cons<Indexable, Tail>, | |
248 | Indexable | |
249 | > | |
250 | {}; | |
251 | ||
7c673cae FG |
252 | }}}} // namespace boost::geometry::index::detail |
253 | ||
254 | #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
255 | ||
256 | #include <tuple> | |
257 | ||
258 | namespace boost { namespace geometry { namespace index { namespace detail { | |
259 | ||
260 | /*! | |
261 | \brief The function object extracting Indexable from Value. | |
262 | ||
263 | This specialization translates from std::tuple<Indexable, Args...>. | |
264 | It's defined if the compiler supports tuples and variadic templates. | |
265 | ||
266 | \tparam Indexable The Indexable type. | |
267 | */ | |
268 | template <typename Indexable, typename ...Args> | |
269 | struct indexable<std::tuple<Indexable, Args...>, false> | |
270 | { | |
271 | typedef std::tuple<Indexable, Args...> value_type; | |
272 | ||
20effc67 | 273 | BOOST_GEOMETRY_STATIC_ASSERT( |
7c673cae | 274 | (detail::is_indexable<Indexable>::value), |
20effc67 TL |
275 | "The first type of std::tuple has to be an Indexable.", |
276 | Indexable); | |
7c673cae FG |
277 | |
278 | /*! \brief The type of result returned by function object. */ | |
279 | typedef Indexable const& result_type; | |
280 | ||
281 | /*! | |
282 | \brief Return indexable extracted from the value. | |
283 | ||
284 | \param v The value. | |
285 | \return The indexable. | |
286 | */ | |
287 | result_type operator()(value_type const& v) const | |
288 | { | |
289 | return std::get<0>(v); | |
290 | } | |
92f5a8d4 TL |
291 | |
292 | /*! | |
293 | \brief Return indexable extracted from compatible type different than value_type. | |
294 | ||
295 | \param v The value. | |
296 | \return The indexable. | |
297 | */ | |
298 | template <typename I, typename ...A> | |
299 | inline result_type operator()(std::tuple<I, A...> const& v) const | |
300 | { | |
20effc67 | 301 | BOOST_GEOMETRY_STATIC_ASSERT( |
92f5a8d4 | 302 | (is_referencable<I, result_type>::value), |
20effc67 TL |
303 | "Unexpected type.", |
304 | std::tuple<I, A...>); | |
92f5a8d4 TL |
305 | return std::get<0>(v); |
306 | } | |
307 | ||
308 | /*! | |
309 | \brief Prevent reference to temporary for types convertible to Value. | |
310 | */ | |
311 | template <typename V> | |
312 | inline result_type operator()(V const& v) const | |
313 | { | |
314 | return indexable_prevent_any_type<Indexable>(v); | |
315 | } | |
7c673cae FG |
316 | }; |
317 | ||
318 | }}}} // namespace boost::geometry::index::detail | |
319 | ||
320 | #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
321 | ||
322 | namespace boost { namespace geometry { namespace index { | |
323 | ||
324 | /*! | |
325 | \brief The function object extracting Indexable from Value. | |
326 | ||
327 | It translates Value object to Indexable object. By default, it can handle Values which are Indexables, | |
328 | std::pair<Indexable, T2>, boost::tuple<Indexable, ...> and std::tuple<Indexable, ...> if STD tuples | |
329 | and variadic templates are supported. | |
330 | ||
331 | \tparam Value The Value type which may be translated directly to the Indexable. | |
332 | */ | |
333 | template <typename Value> | |
334 | struct indexable | |
335 | : detail::indexable<Value> | |
336 | { | |
337 | /*! \brief The type of result returned by function object. It should be const Indexable reference. */ | |
338 | typedef typename detail::indexable<Value>::result_type result_type; | |
339 | ||
340 | /*! | |
341 | \brief Return indexable extracted from the value. | |
342 | ||
343 | \param v The value. | |
344 | \return The indexable. | |
345 | */ | |
346 | inline result_type operator()(Value const& v) const | |
347 | { | |
348 | return detail::indexable<Value>::operator()(v); | |
349 | } | |
92f5a8d4 TL |
350 | |
351 | /*! | |
352 | \brief Return indexable extracted from the value. Overload for types | |
353 | compatible with Value but different yet holding referencable | |
354 | Indexable, e.g. tuple containing a reference. | |
355 | ||
356 | \param v The value. | |
357 | \return The indexable. | |
358 | */ | |
359 | template <typename V> | |
360 | inline result_type operator()(V const& v) const | |
361 | { | |
362 | return detail::indexable<Value>::operator()(v); | |
363 | } | |
7c673cae FG |
364 | }; |
365 | ||
366 | }}} // namespace boost::geometry::index | |
367 | ||
368 | #endif // BOOST_GEOMETRY_INDEX_INDEXABLE_HPP |