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