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