File indexing completed on 2025-01-18 09:35:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
0022
0023 #include <algorithm>
0024
0025 #include <boost/range/begin.hpp>
0026 #include <boost/range/end.hpp>
0027
0028 #include <boost/geometry/algorithms/detail/multi_modify.hpp>
0029 #include <boost/geometry/algorithms/detail/visit.hpp>
0030 #include <boost/geometry/core/interior_rings.hpp>
0031 #include <boost/geometry/core/tags.hpp>
0032 #include <boost/geometry/core/visit.hpp>
0033 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0034 #include <boost/geometry/geometries/concepts/check.hpp>
0035
0036
0037 namespace boost { namespace geometry
0038 {
0039
0040
0041 #ifndef DOXYGEN_NO_DETAIL
0042 namespace detail { namespace reverse
0043 {
0044
0045
0046 struct range_reverse
0047 {
0048 template <typename Range>
0049 static inline void apply(Range& range)
0050 {
0051 std::reverse(boost::begin(range), boost::end(range));
0052 }
0053 };
0054
0055
0056 struct polygon_reverse: private range_reverse
0057 {
0058 template <typename Polygon>
0059 static inline void apply(Polygon& polygon)
0060 {
0061 range_reverse::apply(exterior_ring(polygon));
0062
0063 auto&& rings = interior_rings(polygon);
0064 auto const end = boost::end(rings);
0065 for (auto it = boost::begin(rings); it != end; ++it)
0066 {
0067 range_reverse::apply(*it);
0068 }
0069 }
0070 };
0071
0072
0073 }}
0074 #endif
0075
0076
0077 #ifndef DOXYGEN_NO_DISPATCH
0078 namespace dispatch
0079 {
0080
0081
0082 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0083 struct reverse
0084 {
0085 static inline void apply(Geometry&)
0086 {}
0087 };
0088
0089
0090 template <typename Ring>
0091 struct reverse<Ring, ring_tag>
0092 : detail::reverse::range_reverse
0093 {};
0094
0095
0096 template <typename LineString>
0097 struct reverse<LineString, linestring_tag>
0098 : detail::reverse::range_reverse
0099 {};
0100
0101
0102 template <typename Polygon>
0103 struct reverse<Polygon, polygon_tag>
0104 : detail::reverse::polygon_reverse
0105 {};
0106
0107
0108 template <typename Geometry>
0109 struct reverse<Geometry, multi_linestring_tag>
0110 : detail::multi_modify<detail::reverse::range_reverse>
0111 {};
0112
0113
0114 template <typename Geometry>
0115 struct reverse<Geometry, multi_polygon_tag>
0116 : detail::multi_modify<detail::reverse::polygon_reverse>
0117 {};
0118
0119
0120
0121 }
0122 #endif
0123
0124
0125 namespace resolve_dynamic
0126 {
0127
0128 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0129 struct reverse
0130 {
0131 static void apply(Geometry& geometry)
0132 {
0133 concepts::check<Geometry>();
0134 dispatch::reverse<Geometry>::apply(geometry);
0135 }
0136 };
0137
0138 template <typename Geometry>
0139 struct reverse<Geometry, dynamic_geometry_tag>
0140 {
0141 static void apply(Geometry& geometry)
0142 {
0143 traits::visit<Geometry>::apply([](auto & g)
0144 {
0145 reverse<util::remove_cref_t<decltype(g)>>::apply(g);
0146 }, geometry);
0147 }
0148 };
0149
0150 template <typename Geometry>
0151 struct reverse<Geometry, geometry_collection_tag>
0152 {
0153 static void apply(Geometry& geometry)
0154 {
0155 detail::visit_breadth_first([](auto & g)
0156 {
0157 reverse<util::remove_cref_t<decltype(g)>>::apply(g);
0158 return true;
0159 }, geometry);
0160 }
0161 };
0162
0163 }
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 template <typename Geometry>
0178 inline void reverse(Geometry& geometry)
0179 {
0180 resolve_dynamic::reverse<Geometry>::apply(geometry);
0181 }
0182
0183 }}
0184
0185
0186 #endif