Made the append algorithm variant-aware.

[SVN r82412]
This commit is contained in:
Bruno Lalande 2013-01-08 23:35:28 +00:00
parent 79ce0f7bb5
commit 2cc83e50a1
2 changed files with 71 additions and 18 deletions

View File

@ -14,17 +14,18 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
#define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
#include <boost/range.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/geometries/variant.hpp>
#include <boost/range.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
namespace boost { namespace geometry
@ -174,7 +175,7 @@ struct append_range<polygon_tag, Polygon, Range>
: detail::append::range_to_polygon<Polygon, Range>
{};
}
} // namespace splitted_dispatch
// Default: append a range (or linestring or ring or whatever) to any geometry
@ -194,6 +195,33 @@ struct append<Geometry, RangeOrPoint, point_tag>
{};
template <typename RangeOrPoint>
struct append_variant_dispatcher: boost::static_visitor<void>
{
RangeOrPoint const& m_range_or_point;
int m_ring_index;
int m_multi_index;
append_variant_dispatcher(RangeOrPoint const& range_or_point,
int ring_index,
int multi_index):
m_range_or_point(range_or_point),
m_ring_index(ring_index),
m_multi_index(multi_index)
{}
template <typename Geometry>
void operator()(Geometry& geometry) const
{
return dispatch::append<Geometry, RangeOrPoint>::apply(
geometry,
m_range_or_point,
m_ring_index,
m_multi_index
);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
@ -215,7 +243,7 @@ struct append<Geometry, RangeOrPoint, point_tag>
*/
template <typename Geometry, typename RangeOrPoint>
inline void append(Geometry& geometry, RangeOrPoint const& range_or_point,
int ring_index = -1, int multi_index = 0)
int ring_index = -1, int multi_index = 0)
{
concept::check<Geometry>();
@ -227,6 +255,22 @@ inline void append(Geometry& geometry, RangeOrPoint const& range_or_point,
}
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename RangeOrPoint>
inline void append(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry,
RangeOrPoint const& range_or_point,
int ring_index = -1, int multi_index = 0)
{
apply_visitor(
dispatch::append_variant_dispatcher<RangeOrPoint>(
range_or_point,
ring_index,
multi_index
),
geometry
);
}
}} // namespace boost::geometry

View File

@ -25,6 +25,7 @@
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>
#include <boost/variant/variant.hpp>
#include <test_common/test_point.hpp>
#include <test_geometries/wrapped_boost_array.hpp>
@ -34,9 +35,8 @@ BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::deque)
template <typename G>
void test_geometry(bool check = true)
void test_geometry(G& geometry, bool check)
{
G geometry;
typedef typename bg::point_type<G>::type P;
bg::append(geometry, bg::make_zero<P>());
@ -66,19 +66,28 @@ void test_geometry(bool check = true)
//P p = boost::range::front(geometry);
}
template <typename G>
void test_geometry_and_variant(bool check = true)
{
G geometry;
boost::variant<G> variant_geometry = G();
test_geometry(geometry, check);
test_geometry(variant_geometry, check);
}
template <typename P>
void test_all()
{
test_geometry<P>(false);
test_geometry<bg::model::box<P> >(false);
test_geometry<bg::model::segment<P> >(false);
test_geometry<bg::model::linestring<P> >();
test_geometry<bg::model::ring<P> >();
test_geometry<bg::model::polygon<P> >();
test_geometry_and_variant<P>(false);
test_geometry_and_variant<bg::model::box<P> >(false);
test_geometry_and_variant<bg::model::segment<P> >(false);
test_geometry_and_variant<bg::model::linestring<P> >();
test_geometry_and_variant<bg::model::ring<P> >();
test_geometry_and_variant<bg::model::polygon<P> >();
test_geometry<std::vector<P> >();
test_geometry<std::deque<P> >();
//test_geometry<std::list<P> >();
test_geometry_and_variant<std::vector<P> >();
test_geometry_and_variant<std::deque<P> >();
//test_geometry_and_variant<std::list<P> >();
}
int test_main(int, char* [])