]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/geometry/core/closure.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / geometry / core / closure.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
6
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13
14 #ifndef BOOST_GEOMETRY_CORE_CLOSURE_HPP
15 #define BOOST_GEOMETRY_CORE_CLOSURE_HPP
16
17
18 #include <boost/mpl/assert.hpp>
19 #include <boost/mpl/int.hpp>
20 #include <boost/range.hpp>
21 #include <boost/type_traits/remove_const.hpp>
22
23 #include <boost/geometry/core/ring_type.hpp>
24 #include <boost/geometry/core/tag.hpp>
25 #include <boost/geometry/core/tags.hpp>
26
27 namespace boost { namespace geometry
28 {
29
30
31 /*!
32 \brief Enumerates options for defining if polygons are open or closed
33 \ingroup enum
34 \details The enumeration closure_selector describes options for if a polygon is
35     open or closed. In a closed polygon the very first point (per ring) should 
36     be equal to the very last point.
37     The specific closing property of a polygon type is defined by the closure 
38     metafunction. The closure metafunction defines a value, which is one of the 
39     values enumerated in the closure_selector
40
41 \qbk{
42 [heading See also]
43 [link geometry.reference.core.closure The closure metafunction]
44 }
45 */
46 enum closure_selector
47 {
48     /// Rings are open: first point and last point are different, algorithms 
49     /// close them explicitly on the fly
50     open = 0,
51     /// Rings are closed: first point and last point must be the same
52     closed = 1,
53     /// (Not yet implemented): algorithms first figure out if ring must be 
54     /// closed on the fly
55     closure_undertermined = -1
56 };
57
58 namespace traits
59 {
60
61 /*!
62     \brief Traits class indicating if points within a
63         ring or (multi)polygon are closed (last point == first point),
64         open or not known.
65     \ingroup traits
66     \par Geometries:
67         - ring
68     \tparam G geometry
69 */
70 template <typename G>
71 struct closure
72 {
73     static const closure_selector value = closed;
74 };
75
76
77 } // namespace traits
78
79
80 #ifndef DOXYGEN_NO_DETAIL
81 namespace core_detail { namespace closure
82 {
83
84 struct closed
85 {
86     static const closure_selector value = geometry::closed;
87 };
88
89
90 /// Metafunction to define the minimum size of a ring:
91 /// 3 for open rings, 4 for closed rings
92 template <closure_selector Closure>
93 struct minimum_ring_size {};
94
95 template <>
96 struct minimum_ring_size<geometry::closed> : boost::mpl::int_<4> {};
97
98 template <>
99 struct minimum_ring_size<geometry::open> : boost::mpl::int_<3> {};
100
101
102 }} // namespace detail::point_order
103 #endif // DOXYGEN_NO_DETAIL
104
105
106
107 #ifndef DOXYGEN_NO_DISPATCH
108 namespace core_dispatch
109 {
110
111 template <typename Tag, typename Geometry>
112 struct closure
113 {
114     BOOST_MPL_ASSERT_MSG
115         (
116             false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
117             , (types<Geometry>)
118         );
119 };
120
121 template <typename Box>
122 struct closure<point_tag, Box> : public core_detail::closure::closed {};
123
124 template <typename Box>
125 struct closure<box_tag, Box> : public core_detail::closure::closed {};
126
127 template <typename Box>
128 struct closure<segment_tag, Box> : public core_detail::closure::closed {};
129
130 template <typename LineString>
131 struct closure<linestring_tag, LineString> 
132     : public core_detail::closure::closed {};
133
134
135 template <typename Ring>
136 struct closure<ring_tag, Ring>
137 {
138     static const closure_selector value 
139         = geometry::traits::closure<Ring>::value;
140 };
141
142 // Specialization for polygon: the closure is the closure of its rings
143 template <typename Polygon>
144 struct closure<polygon_tag, Polygon>
145 {
146     static const closure_selector value = core_dispatch::closure
147         <
148             ring_tag,
149             typename ring_type<polygon_tag, Polygon>::type
150         >::value ;
151 };
152
153
154 } // namespace core_dispatch
155 #endif // DOXYGEN_NO_DISPATCH
156
157
158 /*!
159 \brief \brief_meta{value, closure (clockwise\, counterclockwise), 
160     \meta_geometry_type}
161 \tparam Geometry \tparam_geometry
162 \ingroup core
163
164 \qbk{[include reference/core/closure.qbk]}
165 */
166 template <typename Geometry>
167 struct closure
168 {
169     static const closure_selector value = core_dispatch::closure
170         <
171             typename tag<Geometry>::type,
172             typename boost::remove_const<Geometry>::type
173         >::value;
174 };
175
176
177 }} // namespace boost::geometry
178
179
180 #endif // BOOST_GEOMETRY_CORE_CLOSURE_HPP