123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
- #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
- #include <boost/geometry/core/access.hpp>
- #include <boost/geometry/core/coordinate_dimension.hpp>
- #include <boost/geometry/core/coordinate_type.hpp>
- #include <boost/geometry/core/static_assert.hpp>
- #include <boost/geometry/core/tag.hpp>
- #include <boost/geometry/core/tags.hpp>
- #include <boost/geometry/util/select_most_precise.hpp>
- namespace boost { namespace geometry { namespace index { namespace detail {
- template <typename Box>
- struct default_margin_result
- {
- using type = typename select_most_precise
- <
- typename coordinate_type<Box>::type,
- double
- >::type;
- };
- template <typename Box,
- std::size_t CurrentDimension = dimension<Box>::value>
- struct simple_margin_for_each_dimension
- {
- BOOST_STATIC_ASSERT(0 < CurrentDimension);
- static inline typename default_margin_result<Box>::type apply(Box const& b)
- {
- return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
- geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
- }
- };
- template <typename Box>
- struct simple_margin_for_each_dimension<Box, 1>
- {
- static inline typename default_margin_result<Box>::type apply(Box const& b)
- {
- return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
- }
- };
- namespace dispatch {
- template <typename Geometry, typename Tag>
- struct comparable_margin
- {
- BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
- "Not implemented for this Geometry type.",
- Geometry, Tag);
- };
- template <typename Geometry>
- struct comparable_margin<Geometry, point_tag>
- {
- typedef typename default_margin_result<Geometry>::type result_type;
- static inline result_type apply(Geometry const& ) { return 0; }
- };
- template <typename Box>
- struct comparable_margin<Box, box_tag>
- {
- typedef typename default_margin_result<Box>::type result_type;
- static inline result_type apply(Box const& g)
- {
-
- return detail::simple_margin_for_each_dimension<Box>::apply(g);
- }
- };
- }
- template <typename Geometry>
- typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
- {
- return dispatch::comparable_margin<
- Geometry,
- typename tag<Geometry>::type
- >::apply(g);
- }
- }}}}
- #endif
|