]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/index/detail/algorithms/margin.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / index / detail / algorithms / margin.hpp
1 // Boost.Geometry Index
2 //
3 // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
4 //
5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
6 //
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
13
14 // WARNING! comparable_margin() will work only if the same Geometries are compared
15 // so it shouldn't be used in the case of Variants!
16
17 namespace boost { namespace geometry { namespace index { namespace detail {
18
19 template <typename Box>
20 struct default_margin_result
21 {
22 typedef typename select_most_precise<
23 typename coordinate_type<Box>::type,
24 long double
25 >::type type;
26 };
27
28 //template <typename Box,
29 // std::size_t CurrentDimension,
30 // std::size_t EdgeDimension = dimension<Box>::value>
31 //struct margin_for_each_edge
32 //{
33 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
34 // BOOST_STATIC_ASSERT(0 < EdgeDimension);
35 //
36 // static inline typename default_margin_result<Box>::type apply(Box const& b)
37 // {
38 // return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
39 // ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
40 // }
41 //};
42 //
43 //template <typename Box, std::size_t CurrentDimension>
44 //struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
45 //{
46 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
47 //
48 // static inline typename default_margin_result<Box>::type apply(Box const& b)
49 // {
50 // return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
51 // }
52 //};
53 //
54 //template <typename Box, std::size_t CurrentDimension>
55 //struct margin_for_each_edge<Box, CurrentDimension, 1>
56 //{
57 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
58 //
59 // static inline typename default_margin_result<Box>::type apply(Box const& b)
60 // {
61 // return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
62 // }
63 //};
64 //
65 //template <typename Box>
66 //struct margin_for_each_edge<Box, 1, 1>
67 //{
68 // static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
69 // {
70 // return 1;
71 // }
72 //};
73 //
74 //template <typename Box,
75 // std::size_t CurrentDimension = dimension<Box>::value>
76 //struct margin_for_each_dimension
77 //{
78 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
79 //
80 // static inline typename default_margin_result<Box>::type apply(Box const& b)
81 // {
82 // return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
83 // margin_for_each_edge<Box, CurrentDimension>::apply(b);
84 // }
85 //};
86 //
87 //template <typename Box>
88 //struct margin_for_each_dimension<Box, 1>
89 //{
90 // static inline typename default_margin_result<Box>::type apply(Box const& b)
91 // {
92 // return margin_for_each_edge<Box, 1>::apply(b);
93 // }
94 //};
95
96 // TODO - test if this definition of margin is ok for Dimension > 2
97 // Now it's sum of edges lengths
98 // maybe margin_for_each_dimension should be used to get more or less hypersurface?
99
100 template <typename Box,
101 std::size_t CurrentDimension = dimension<Box>::value>
102 struct simple_margin_for_each_dimension
103 {
104 BOOST_STATIC_ASSERT(0 < CurrentDimension);
105
106 static inline typename default_margin_result<Box>::type apply(Box const& b)
107 {
108 return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
109 geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
110 }
111 };
112
113 template <typename Box>
114 struct simple_margin_for_each_dimension<Box, 1>
115 {
116 static inline typename default_margin_result<Box>::type apply(Box const& b)
117 {
118 return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
119 }
120 };
121
122 namespace dispatch {
123
124 template <typename Geometry, typename Tag>
125 struct comparable_margin
126 {
127 BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
128 };
129
130 template <typename Geometry>
131 struct comparable_margin<Geometry, point_tag>
132 {
133 typedef typename default_margin_result<Geometry>::type result_type;
134
135 static inline result_type apply(Geometry const& ) { return 0; }
136 };
137
138 template <typename Box>
139 struct comparable_margin<Box, box_tag>
140 {
141 typedef typename default_margin_result<Box>::type result_type;
142
143 static inline result_type apply(Box const& g)
144 {
145 //return detail::margin_for_each_dimension<Box>::apply(g);
146 return detail::simple_margin_for_each_dimension<Box>::apply(g);
147 }
148 };
149
150 } // namespace dispatch
151
152 template <typename Geometry>
153 typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
154 {
155 return dispatch::comparable_margin<
156 Geometry,
157 typename tag<Geometry>::type
158 >::apply(g);
159 }
160
161 //template <typename Box>
162 //typename default_margin_result<Box>::type margin(Box const& b)
163 //{
164 // return 2 * detail::margin_for_each_dimension<Box>::apply(b);
165 //}
166
167 }}}} // namespace boost::geometry::index::detail
168
169 #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP