Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / geometry / algorithms / detail / buffer / buffered_ring.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
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_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
11
12
13 #include <cstddef>
14
15 #include <boost/range.hpp>
16
17 #include <boost/geometry/core/coordinate_type.hpp>
18 #include <boost/geometry/core/point_type.hpp>
19
20 #include <boost/geometry/strategies/buffer.hpp>
21
22 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
23 #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
24 #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
25 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
26 #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
27 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
28
29 #include <boost/geometry/multi/algorithms/within.hpp>
30
31
32 namespace boost { namespace geometry
33 {
34
35 #ifndef DOXYGEN_NO_DETAIL
36 namespace detail { namespace buffer
37 {
38
39 struct buffered_ring_collection_tag : polygonal_tag, multi_tag
40 {};
41
42
43 template <typename Ring>
44 struct buffered_ring : public Ring
45 {
46     bool has_accepted_intersections;
47     bool has_discarded_intersections;
48
49     inline buffered_ring()
50         : has_accepted_intersections(false)
51         , has_discarded_intersections(false)
52     {}
53
54     inline bool discarded() const
55     {
56         return has_discarded_intersections && ! has_accepted_intersections;
57     }
58     inline bool has_intersections() const
59     {
60         return has_discarded_intersections || has_accepted_intersections;
61     }
62 };
63
64 // This is a collection now special for overlay (needs vector of rings)
65 template <typename Ring>
66 struct buffered_ring_collection : public std::vector<Ring>
67 {
68 };
69
70 }} // namespace detail::buffer
71
72
73 // Turn off concept checking (for now)
74 namespace dispatch
75 {
76 template <typename Geometry, bool IsConst>
77 struct check<Geometry, detail::buffer::buffered_ring_collection_tag, IsConst>
78 {
79 };
80
81 }
82
83
84 #endif // DOXYGEN_NO_DETAIL
85
86
87
88 // Register the types
89 namespace traits
90 {
91
92
93 template <typename Ring>
94 struct tag<detail::buffer::buffered_ring<Ring> >
95 {
96     typedef ring_tag type;
97 };
98
99
100 template <typename Ring>
101 struct point_order<detail::buffer::buffered_ring<Ring> >
102 {
103     static const order_selector value = geometry::point_order<Ring>::value;
104 };
105
106
107 template <typename Ring>
108 struct closure<detail::buffer::buffered_ring<Ring> >
109 {
110     static const closure_selector value = geometry::closure<Ring>::value;
111 };
112
113
114 template <typename Ring>
115 struct point_type<detail::buffer::buffered_ring_collection<Ring> >
116 {
117     typedef typename geometry::point_type<Ring>::type type;
118 };
119
120 template <typename Ring>
121 struct tag<detail::buffer::buffered_ring_collection<Ring> >
122 {
123     typedef detail::buffer::buffered_ring_collection_tag type;
124 };
125
126
127 } // namespace traits
128
129
130
131
132 namespace core_dispatch
133 {
134
135 template <typename Ring>
136 struct ring_type
137 <
138     detail::buffer::buffered_ring_collection_tag,
139     detail::buffer::buffered_ring_collection<Ring>
140 >
141 {
142     typedef Ring type;
143 };
144
145 }
146
147 namespace dispatch
148 {
149
150 template
151 <
152     typename MultiRing,
153     bool Reverse,
154     typename SegmentIdentifier,
155     typename PointOut
156 >
157 struct copy_segment_point
158     <
159         detail::buffer::buffered_ring_collection_tag,
160         MultiRing,
161         Reverse,
162         SegmentIdentifier,
163         PointOut
164     >
165     : detail::copy_segments::copy_segment_point_multi
166         <
167             MultiRing,
168             SegmentIdentifier,
169             PointOut,
170             detail::copy_segments::copy_segment_point_range
171                 <
172                     typename boost::range_value<MultiRing>::type,
173                     Reverse,
174                     SegmentIdentifier,
175                     PointOut
176                 >
177         >
178 {};
179
180
181 template<bool Reverse>
182 struct copy_segments
183     <
184         detail::buffer::buffered_ring_collection_tag,
185         Reverse
186     >
187     : detail::copy_segments::copy_segments_multi
188         <
189             detail::copy_segments::copy_segments_ring<Reverse>
190         >
191 {};
192
193 template <typename Point, typename MultiGeometry>
194 struct within
195 <
196     Point,
197     MultiGeometry,
198     point_tag,
199     detail::buffer::buffered_ring_collection_tag
200 >
201 {
202     template <typename Strategy>
203     static inline bool apply(Point const& point,
204                 MultiGeometry const& multi, Strategy const& strategy)
205     {
206         return detail::within::point_in_geometry(point, multi, strategy) == 1;
207     }
208 };
209
210
211 } // namespace dispatch
212
213 namespace detail { namespace overlay
214 {
215
216 template<>
217 struct get_ring<detail::buffer::buffered_ring_collection_tag>
218 {
219     template<typename MultiGeometry>
220     static inline typename ring_type<MultiGeometry>::type const& apply(
221                 ring_identifier const& id,
222                 MultiGeometry const& multi_ring)
223     {
224         BOOST_ASSERT
225             (
226                 id.multi_index >= 0
227                 && id.multi_index < int(boost::size(multi_ring))
228             );
229         return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]);
230     }
231 };
232
233 }}
234
235
236 }} // namespace boost::geometry
237
238 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING