1 // Boost.Geometry Index
2 //
3 // Copyright (c) 2011-2014 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 
14 namespace boost { namespace geometry { namespace index { namespace detail {
15 
16 template <typename Geometry, typename GeometryTag>
17 struct is_indexable_impl { static const bool value = false; };
18 
19 template <typename Point>
20 struct is_indexable_impl<Point, geometry::point_tag> { static const bool value = true; };
21 
22 template <typename Box>
23 struct is_indexable_impl<Box, geometry::box_tag> { static const bool value = true; };
24 
25 template <typename Segment>
26 struct is_indexable_impl<Segment, geometry::segment_tag> { static const bool value = true; };
27 
28 template <typename Indexable>
29 struct is_indexable
30 {
31     static const bool value =
32         is_indexable_impl
33             <
34                 Indexable,
35                 typename geometry::tag<Indexable>::type
36             >::value;
37 };
38 
39 /*!
40 \brief The function object extracting Indexable from Value.
41 
42 It translates Value object to Indexable object. The default version handles Values which are Indexables.
43 This template is also specialized for std::pair<Indexable, T2>, boost::tuple<Indexable, ...>
44 and std::tuple<Indexable, ...>.
45 
46 \tparam Value       The Value type which may be translated directly to the Indexable.
47 \tparam IsIndexable If true, the const reference to Value is returned.
48 */
49 template <typename Value, bool IsIndexable = is_indexable<Value>::value>
50 struct indexable
51 {
52     BOOST_MPL_ASSERT_MSG(
53         (detail::is_indexable<Value>::value),
54         NOT_VALID_INDEXABLE_TYPE,
55         (Value)
56     );
57 
58     /*! \brief The type of result returned by function object. */
59     typedef Value const& result_type;
60 
61     /*!
62     \brief Return indexable extracted from the value.
63 
64     \param v The value.
65     \return The indexable.
66     */
operator ()boost::geometry::index::detail::indexable67     inline result_type operator()(Value const& v) const
68     {
69         return v;
70     }
71 };
72 
73 /*!
74 \brief The function object extracting Indexable from Value.
75 
76 This specialization translates from std::pair<Indexable, T2>.
77 
78 \tparam Indexable       The Indexable type.
79 \tparam T2              The second type.
80 */
81 template <typename Indexable, typename T2>
82 struct indexable<std::pair<Indexable, T2>, false>
83 {
84     BOOST_MPL_ASSERT_MSG(
85         (detail::is_indexable<Indexable>::value),
86         NOT_VALID_INDEXABLE_TYPE,
87         (Indexable)
88     );
89 
90     /*! \brief The type of result returned by function object. */
91     typedef Indexable const& result_type;
92 
93     /*!
94     \brief Return indexable extracted from the value.
95 
96     \param v The value.
97     \return The indexable.
98     */
operator ()boost::geometry::index::detail::indexable99     inline result_type operator()(std::pair<Indexable, T2> const& v) const
100     {
101         return v.first;
102     }
103 };
104 
105 /*!
106 \brief The function object extracting Indexable from Value.
107 
108 This specialization translates from boost::tuple<Indexable, ...>.
109 
110 \tparam Indexable   The Indexable type.
111 */
112 template <typename Indexable, typename T1, typename T2, typename T3, typename T4,
113           typename T5, typename T6, typename T7, typename T8, typename T9>
114 struct indexable<boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false>
115 {
116     typedef boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9> value_type;
117 
118     BOOST_MPL_ASSERT_MSG(
119         (detail::is_indexable<Indexable>::value),
120         NOT_VALID_INDEXABLE_TYPE,
121         (Indexable)
122         );
123 
124     /*! \brief The type of result returned by function object. */
125     typedef Indexable const& result_type;
126 
127     /*!
128     \brief Return indexable extracted from the value.
129 
130     \param v The value.
131     \return The indexable.
132     */
operator ()boost::geometry::index::detail::indexable133     inline result_type operator()(value_type const& v) const
134     {
135         return boost::get<0>(v);
136     }
137 };
138 
139 }}}} // namespace boost::geometry::index::detail
140 
141 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
142 
143 #include <tuple>
144 
145 namespace boost { namespace geometry { namespace index { namespace detail {
146 
147 /*!
148 \brief The function object extracting Indexable from Value.
149 
150 This specialization translates from std::tuple<Indexable, Args...>.
151 It's defined if the compiler supports tuples and variadic templates.
152 
153 \tparam Indexable   The Indexable type.
154 */
155 template <typename Indexable, typename ...Args>
156 struct indexable<std::tuple<Indexable, Args...>, false>
157 {
158     typedef std::tuple<Indexable, Args...> value_type;
159 
160     BOOST_MPL_ASSERT_MSG(
161         (detail::is_indexable<Indexable>::value),
162         NOT_VALID_INDEXABLE_TYPE,
163         (Indexable)
164         );
165 
166     /*! \brief The type of result returned by function object. */
167     typedef Indexable const& result_type;
168 
169     /*!
170     \brief Return indexable extracted from the value.
171 
172     \param v The value.
173     \return The indexable.
174     */
operator ()boost::geometry::index::detail::indexable175     result_type operator()(value_type const& v) const
176     {
177         return std::get<0>(v);
178     }
179 };
180 
181 }}}} // namespace boost::geometry::index::detail
182 
183 #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
184 
185 namespace boost { namespace geometry { namespace index {
186 
187 /*!
188 \brief The function object extracting Indexable from Value.
189 
190 It translates Value object to Indexable object. By default, it can handle Values which are Indexables,
191 std::pair<Indexable, T2>, boost::tuple<Indexable, ...> and std::tuple<Indexable, ...> if STD tuples
192 and variadic templates are supported.
193 
194 \tparam Value       The Value type which may be translated directly to the Indexable.
195 */
196 template <typename Value>
197 struct indexable
198     : detail::indexable<Value>
199 {
200     /*! \brief The type of result returned by function object. It should be const Indexable reference. */
201     typedef typename detail::indexable<Value>::result_type result_type;
202 
203     /*!
204     \brief Return indexable extracted from the value.
205 
206     \param v The value.
207     \return The indexable.
208     */
operator ()boost::geometry::index::indexable209     inline result_type operator()(Value const& v) const
210     {
211         return detail::indexable<Value>::operator()(v);
212     }
213 };
214 
215 }}} // namespace boost::geometry::index
216 
217 #endif // BOOST_GEOMETRY_INDEX_INDEXABLE_HPP
218