1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2015, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 7 // Licensed under the Boost Software License version 1.0. 8 // http://www.boost.org/users/license.html 9 10 #ifndef BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP 11 #define BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP 12 13 #include <cstddef> 14 15 #include <boost/mpl/assert.hpp> 16 #include <boost/mpl/int.hpp> 17 18 #include <boost/geometry/core/access.hpp> 19 #include <boost/geometry/core/coordinate_type.hpp> 20 #include <boost/geometry/core/coordinate_system.hpp> 21 #include <boost/geometry/core/coordinate_dimension.hpp> 22 #include <boost/geometry/core/point_type.hpp> 23 #include <boost/geometry/core/tag.hpp> 24 #include <boost/geometry/core/tags.hpp> 25 26 #include <boost/geometry/algorithms/not_implemented.hpp> 27 28 29 namespace boost { namespace geometry 30 { 31 32 #ifndef DOXYGEN_NO_DETAIL 33 namespace detail 34 { 35 36 template 37 < 38 typename Geometry, 39 std::size_t Dimension1 = 0, 40 std::size_t Dimension2 = 1, 41 typename Tag = typename tag<Geometry>::type 42 > 43 struct two_dimensional_view 44 : not_implemented<Tag> 45 {}; 46 47 48 // View that enables to choose two dimensions of a point and see it as 49 // a two-dimensional point 50 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 51 struct two_dimensional_view<Point, Dimension1, Dimension2, point_tag> 52 { 53 BOOST_MPL_ASSERT_MSG( 54 (Dimension1 < static_cast<std::size_t>(dimension<Point>::value)), 55 COORDINATE_DIMENSION1_IS_LARGER_THAN_POINT_DIMENSION, 56 (boost::mpl::int_<Dimension1>)); 57 58 BOOST_MPL_ASSERT_MSG( 59 (Dimension2 < static_cast<std::size_t>(dimension<Point>::value)), 60 COORDINATE_DIMENSION2_IS_LARGER_THAN_POINT_DIMENSION, 61 (boost::mpl::int_<Dimension2>)); 62 two_dimensional_viewboost::geometry::detail::two_dimensional_view63 two_dimensional_view(Point& point) 64 : m_point(point) 65 {} 66 67 Point& m_point; 68 }; 69 70 71 } // namespace detail 72 #endif // DOXYGEN_NO_DETAIL 73 74 75 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS 76 namespace traits 77 { 78 79 80 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 81 struct tag 82 < 83 geometry::detail::two_dimensional_view 84 < 85 Point, Dimension1, Dimension2, point_tag 86 > 87 > 88 { 89 typedef point_tag type; 90 }; 91 92 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 93 struct coordinate_system 94 < 95 geometry::detail::two_dimensional_view 96 < 97 Point, Dimension1, Dimension2, point_tag 98 > 99 > : coordinate_system<typename geometry::point_type<Point>::type> 100 {}; 101 102 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 103 struct coordinate_type 104 < 105 geometry::detail::two_dimensional_view 106 < 107 Point, Dimension1, Dimension2, point_tag 108 > 109 > : coordinate_type<typename geometry::point_type<Point>::type> 110 {}; 111 112 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 113 struct dimension 114 < 115 geometry::detail::two_dimensional_view 116 < 117 Point, Dimension1, Dimension2, point_tag 118 > 119 > : boost::mpl::int_<2> 120 {}; 121 122 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 123 struct point_type 124 < 125 geometry::detail::two_dimensional_view 126 < 127 Point, Dimension1, Dimension2, point_tag 128 > 129 > 130 { 131 typedef typename geometry::point_type<Point>::type type; 132 }; 133 134 135 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 136 struct access 137 < 138 geometry::detail::two_dimensional_view 139 < 140 Point, Dimension1, Dimension2, point_tag 141 >, 142 0 143 > 144 { 145 typedef typename geometry::coordinate_type<Point>::type coordinate_type; 146 typedef geometry::detail::two_dimensional_view 147 < 148 Point, Dimension1, Dimension2, point_tag 149 > view_type; 150 getboost::geometry::traits::access151 static inline coordinate_type get(view_type const& view) 152 { 153 return geometry::get<Dimension1>(view.m_point); 154 } 155 setboost::geometry::traits::access156 static inline void set(view_type& view, coordinate_type const& value) 157 { 158 geometry::set<Dimension1>(view.m_point, value); 159 } 160 }; 161 162 template <typename Point, std::size_t Dimension1, std::size_t Dimension2> 163 struct access 164 < 165 geometry::detail::two_dimensional_view 166 < 167 Point, Dimension1, Dimension2, point_tag 168 >, 169 1 170 > 171 { 172 typedef typename geometry::coordinate_type<Point>::type coordinate_type; 173 typedef geometry::detail::two_dimensional_view 174 < 175 Point, Dimension1, Dimension2, point_tag 176 > view_type; 177 getboost::geometry::traits::access178 static inline coordinate_type get(view_type const& view) 179 { 180 return geometry::get<Dimension2>(view.m_point); 181 } 182 setboost::geometry::traits::access183 static inline void set(view_type& view, coordinate_type const& value) 184 { 185 geometry::set<Dimension2>(view.m_point, value); 186 } 187 }; 188 189 190 } // namespace traits 191 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS 192 193 }} // namespace boost::geometry 194 195 196 #endif // BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP 197