1 // Boost.Geometry Index
3 // Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
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)
9 #ifndef BOOST_GEOMETRY_INDEX_INDEXABLE_HPP
10 #define BOOST_GEOMETRY_INDEX_INDEXABLE_HPP
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>
19 #include <boost/geometry/index/detail/is_indexable.hpp>
21 namespace boost { namespace geometry { namespace index { namespace detail {
27 typename boost::remove_reference<T>::type
31 template <typename From, typename To>
32 struct is_referencable
35 typename remove_cr<From>::type,
36 typename remove_cr<To>::type
40 template <typename Indexable, typename V>
41 inline Indexable const& indexable_prevent_any_type(V const& )
52 \brief The function object extracting Indexable from Value.
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, ...>.
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.
61 template <typename Value, bool IsIndexable = is_indexable<Value>::value>
65 (detail::is_indexable<Value>::value),
66 NOT_VALID_INDEXABLE_TYPE,
70 /*! \brief The type of result returned by function object. */
71 typedef Value const& result_type;
74 \brief Return indexable extracted from the value.
77 \return The indexable.
79 inline result_type operator()(Value const& v) const
85 \brief Prevent reference to temporary for types convertible to Value.
88 inline result_type operator()(V const& v) const
90 return indexable_prevent_any_type<Value>(v);
95 \brief The function object extracting Indexable from Value.
97 This specialization translates from std::pair<Indexable, T2>.
99 \tparam Indexable The Indexable type.
100 \tparam Second The second type.
102 template <typename Indexable, typename Second>
103 struct indexable<std::pair<Indexable, Second>, false>
105 typedef std::pair<Indexable, Second> value_type;
107 BOOST_MPL_ASSERT_MSG(
108 (detail::is_indexable<Indexable>::value),
109 NOT_VALID_INDEXABLE_TYPE,
113 /*! \brief The type of result returned by function object. */
114 typedef Indexable const& result_type;
117 \brief Return indexable extracted from the value.
120 \return The indexable.
122 inline result_type operator()(value_type const& v) const
128 \brief Return indexable extracted from compatible type different than value_type.
131 \return The indexable.
133 template <typename I, typename S>
134 inline result_type operator()(std::pair<I, S> const& v) const
136 BOOST_MPL_ASSERT_MSG(
137 (is_referencable<I, result_type>::value),
145 \brief Prevent reference to temporary for types convertible to Value.
147 template <typename V>
148 inline result_type operator()(V const& v) const
150 return indexable_prevent_any_type<Indexable>(v);
155 \brief The function object extracting Indexable from Value.
157 This specialization translates from boost::tuple<Indexable, ...>
158 or boost::tuples::cons<Indexable, ...>.
160 \tparam Value The Value type.
161 \tparam Indexable The Indexable type.
163 template <typename Value, typename Indexable>
164 struct indexable_boost_tuple
166 typedef Value value_type;
168 BOOST_MPL_ASSERT_MSG(
169 (detail::is_indexable<Indexable>::value),
170 NOT_VALID_INDEXABLE_TYPE,
174 /*! \brief The type of result returned by function object. */
175 typedef Indexable const& result_type;
178 \brief Return indexable extracted from the value.
181 \return The indexable.
183 inline result_type operator()(value_type const& v) const
185 return boost::get<0>(v);
189 \brief Return indexable extracted from compatible type different than value_type.
192 \return The indexable.
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
198 BOOST_MPL_ASSERT_MSG(
199 (is_referencable<I, result_type>::value),
201 (boost::tuple<I, U1, U2, U3, U4, U5, U6, U7, U8, U9>)
203 return boost::get<0>(v);
207 \brief Return indexable extracted from compatible type different than value_type.
210 \return The indexable.
212 template <typename I, typename T>
213 inline result_type operator()(boost::tuples::cons<I, T> const& v) const
215 BOOST_MPL_ASSERT_MSG(
216 (is_referencable<I, result_type>::value),
218 (boost::tuples::cons<I, T>)
220 return boost::get<0>(v);
224 \brief Prevent reference to temporary for types convertible to Value.
226 template <typename V>
227 inline result_type operator()(V const& v) const
229 return indexable_prevent_any_type<Indexable>(v);
234 \brief The function object extracting Indexable from Value.
236 This specialization translates from boost::tuple<Indexable, ...>.
238 \tparam Indexable The Indexable type.
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
245 boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
251 \brief The function object extracting Indexable from Value.
253 This specialization translates from boost::tuples::cons<Indexable, ...>.
255 \tparam Indexable The Indexable type.
257 template <typename Indexable, typename Tail>
258 struct indexable<boost::tuples::cons<Indexable, Tail>, false>
259 : indexable_boost_tuple
261 boost::tuples::cons<Indexable, Tail>,
266 }}}} // namespace boost::geometry::index::detail
268 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
272 namespace boost { namespace geometry { namespace index { namespace detail {
275 \brief The function object extracting Indexable from Value.
277 This specialization translates from std::tuple<Indexable, Args...>.
278 It's defined if the compiler supports tuples and variadic templates.
280 \tparam Indexable The Indexable type.
282 template <typename Indexable, typename ...Args>
283 struct indexable<std::tuple<Indexable, Args...>, false>
285 typedef std::tuple<Indexable, Args...> value_type;
287 BOOST_MPL_ASSERT_MSG(
288 (detail::is_indexable<Indexable>::value),
289 NOT_VALID_INDEXABLE_TYPE,
293 /*! \brief The type of result returned by function object. */
294 typedef Indexable const& result_type;
297 \brief Return indexable extracted from the value.
300 \return The indexable.
302 result_type operator()(value_type const& v) const
304 return std::get<0>(v);
308 \brief Return indexable extracted from compatible type different than value_type.
311 \return The indexable.
313 template <typename I, typename ...A>
314 inline result_type operator()(std::tuple<I, A...> const& v) const
316 BOOST_MPL_ASSERT_MSG(
317 (is_referencable<I, result_type>::value),
319 (std::tuple<I, A...>)
321 return std::get<0>(v);
325 \brief Prevent reference to temporary for types convertible to Value.
327 template <typename V>
328 inline result_type operator()(V const& v) const
330 return indexable_prevent_any_type<Indexable>(v);
334 }}}} // namespace boost::geometry::index::detail
336 #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
338 namespace boost { namespace geometry { namespace index {
341 \brief The function object extracting Indexable from Value.
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.
347 \tparam Value The Value type which may be translated directly to the Indexable.
349 template <typename Value>
351 : detail::indexable<Value>
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;
357 \brief Return indexable extracted from the value.
360 \return The indexable.
362 inline result_type operator()(Value const& v) const
364 return detail::indexable<Value>::operator()(v);
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.
373 \return The indexable.
375 template <typename V>
376 inline result_type operator()(V const& v) const
378 return detail::indexable<Value>::operator()(v);
382 }}} // namespace boost::geometry::index
384 #endif // BOOST_GEOMETRY_INDEX_INDEXABLE_HPP