]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/algorithms/num_segments.hpp
buildsys: switch source download to quincy
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / num_segments.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2014, 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_ALGORITHMS_NUM_SEGMENTS_HPP
11#define BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
12
13#include <cstddef>
14
15#include <boost/mpl/size_t.hpp>
16#include <boost/mpl/times.hpp>
17
18#include <boost/range.hpp>
19
20#include <boost/variant/apply_visitor.hpp>
21#include <boost/variant/static_visitor.hpp>
22#include <boost/variant/variant_fwd.hpp>
23
24#include <boost/geometry/core/closure.hpp>
25#include <boost/geometry/core/tag.hpp>
26#include <boost/geometry/core/tags.hpp>
27
28#include <boost/geometry/util/range.hpp>
29
30#include <boost/geometry/geometries/concepts/check.hpp>
31
32#include <boost/geometry/algorithms/not_implemented.hpp>
33
34#include <boost/geometry/algorithms/detail/counting.hpp>
35
36
37namespace boost { namespace geometry
38{
39
40#ifndef DOXYGEN_NO_DETAIL
41namespace detail { namespace num_segments
42{
43
44
45struct range_count
46{
47 template <typename Range>
48 static inline std::size_t apply(Range const& range)
49 {
50 std::size_t n = boost::size(range);
51 if ( n <= 1 )
52 {
53 return 0;
54 }
55
56 return
57 geometry::closure<Range>::value == open
58 ?
59 n
60 :
61 static_cast<std::size_t>(n - 1);
62 }
63};
64
65}} // namespace detail::num_segments
66#endif // DOXYGEN_NO_DETAIL
67
68
69
70#ifndef DOXYGEN_NO_DISPATCH
71namespace dispatch
72{
73
74template <typename Geometry, typename Tag = typename tag<Geometry>::type>
75struct num_segments
76 : not_implemented<Tag>
77{};
78
79template <typename Geometry>
80struct num_segments<Geometry, point_tag>
81 : detail::counting::other_count<0>
82{};
83
84// the number of segments (1-dimensional faces) of the hypercube is
85// given by the formula: d * 2^(d-1), where d is the dimension of the
86// hypercube; see also:
87// http://en.wikipedia.org/wiki/Hypercube
88template <typename Geometry>
89struct num_segments<Geometry, box_tag>
90 : detail::counting::other_count
91 <
92 geometry::dimension<Geometry>::value
93 * (1 << (geometry::dimension<Geometry>::value - 1))
94 >
95{};
96
97template <typename Geometry>
98struct num_segments<Geometry, segment_tag>
99 : detail::counting::other_count<1>
100{};
101
102template <typename Geometry>
103struct num_segments<Geometry, linestring_tag>
104 : detail::num_segments::range_count
105{};
106
107template <typename Geometry>
108struct num_segments<Geometry, ring_tag>
109 : detail::num_segments::range_count
110{};
111
112template <typename Geometry>
113struct num_segments<Geometry, polygon_tag>
114 : detail::counting::polygon_count<detail::num_segments::range_count>
115{};
116
117template <typename Geometry>
118struct num_segments<Geometry, multi_point_tag>
119 : detail::counting::other_count<0>
120{};
121
122template <typename Geometry>
123struct num_segments<Geometry, multi_linestring_tag>
124 : detail::counting::multi_count
125 <
126 num_segments< typename boost::range_value<Geometry>::type>
127 >
128{};
129
130template <typename Geometry>
131struct num_segments<Geometry, multi_polygon_tag>
132 : detail::counting::multi_count
133 <
134 num_segments< typename boost::range_value<Geometry>::type>
135 >
136{};
137
138
139} // namespace dispatch
140#endif // DOXYGEN_NO_DISPATCH
141
142
143
144namespace resolve_variant
145{
146
147
148template <typename Geometry>
149struct num_segments
150{
151 static inline std::size_t apply(Geometry const& geometry)
152 {
153 concepts::check<Geometry const>();
154
155 return dispatch::num_segments<Geometry>::apply(geometry);
156 }
157};
158
159
160template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
161struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
162{
163 struct visitor: boost::static_visitor<std::size_t>
164 {
165 template <typename Geometry>
166 inline std::size_t operator()(Geometry const& geometry) const
167 {
168 return num_segments<Geometry>::apply(geometry);
169 }
170 };
171
172 static inline std::size_t
173 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
174 {
175 return boost::apply_visitor(visitor(), geometry);
176 }
177};
178
179
180} // namespace resolve_variant
181
182
183
184/*!
185\brief \brief_calc{number of segments}
186\ingroup num_segments
187\details \details_calc{num_segments, number of segments}.
188\tparam Geometry \tparam_geometry
189\param geometry \param_geometry
190\return \return_calc{number of segments}
191
192\qbk{[include reference/algorithms/num_segments.qbk]}
193*/
194template <typename Geometry>
195inline std::size_t num_segments(Geometry const& geometry)
196{
197 return resolve_variant::num_segments<Geometry>::apply(geometry);
198}
199
200
201
202}} // namespace boost::geometry
203
204#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP