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