mapnik/test/unit/geometry/geometry_equal.hpp

235 lines
6.1 KiB
C++
Raw Normal View History

#ifndef MAPNIK_UNIT_GEOMETRY_EQUAL
#define MAPNIK_UNIT_GEOMETRY_EQUAL
#include "catch.hpp"
// boost
#include <type_traits>
#include <iterator>
2015-05-15 23:42:12 +02:00
#include <mapnik/warning.hpp>
MAPNIK_DISABLE_WARNING_PUSH
#include <mapnik/warning_ignore.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/range/iterator_range.hpp>
MAPNIK_DISABLE_WARNING_POP
// helper namespace to ensure correct functionality
2022-01-26 23:25:53 +01:00
namespace aux {
namespace adl {
using std::begin;
using std::end;
template<class T>
auto do_begin(T& v) -> decltype(begin(v));
template<class T>
auto do_end(T& v) -> decltype(end(v));
2022-01-26 23:25:53 +01:00
} // namespace adl
template<class... Its>
using zipper_it = boost::zip_iterator<boost::tuple<Its...>>;
template<class T>
2022-01-26 23:25:53 +01:00
T const& as_const(T const& v)
{
return v;
}
} // namespace aux
template<class... Conts>
2022-01-26 23:25:53 +01:00
auto zip_begin(Conts&... conts) -> aux::zipper_it<decltype(aux::adl::do_begin(conts))...>
{
2022-01-26 23:25:53 +01:00
using std::begin;
return {boost::make_tuple(begin(conts)...)};
}
template<class... Conts>
2022-01-26 23:25:53 +01:00
auto zip_end(Conts&... conts) -> aux::zipper_it<decltype(aux::adl::do_end(conts))...>
{
2022-01-26 23:25:53 +01:00
using std::end;
return {boost::make_tuple(end(conts)...)};
}
template<class... Conts>
2022-01-26 23:25:53 +01:00
auto zip_range(Conts&... conts) -> boost::iterator_range<decltype(zip_begin(conts...))>
{
2022-01-26 23:25:53 +01:00
return {zip_begin(conts...), zip_end(conts...)};
}
// for const access
template<class... Conts>
2022-01-26 23:25:53 +01:00
auto zip_cbegin(Conts&... conts) -> decltype(zip_begin(aux::as_const(conts)...))
{
2022-01-26 23:25:53 +01:00
using std::begin;
return zip_begin(aux::as_const(conts)...);
}
template<class... Conts>
2022-01-26 23:25:53 +01:00
auto zip_cend(Conts&... conts) -> decltype(zip_end(aux::as_const(conts)...))
{
2022-01-26 23:25:53 +01:00
using std::end;
return zip_end(aux::as_const(conts)...);
}
template<class... Conts>
2022-01-26 23:25:53 +01:00
auto zip_crange(Conts&... conts) -> decltype(zip_range(aux::as_const(conts)...))
{
2022-01-26 23:25:53 +01:00
return zip_range(aux::as_const(conts)...);
}
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/util/variant.hpp>
using mapnik::geometry::geometry;
2022-01-26 23:25:53 +01:00
using mapnik::geometry::geometry_collection;
using mapnik::geometry::geometry_empty;
using mapnik::geometry::line_string;
using mapnik::geometry::multi_line_string;
2022-01-26 23:25:53 +01:00
using mapnik::geometry::multi_point;
using mapnik::geometry::multi_polygon;
2022-01-26 23:25:53 +01:00
using mapnik::geometry::point;
using mapnik::geometry::polygon;
2022-01-26 23:25:53 +01:00
template<typename T>
2015-04-09 22:22:51 +02:00
void assert_g_equal(geometry<T> const& g1, geometry<T> const& g2);
struct geometry_equal_visitor
{
2022-01-26 23:25:53 +01:00
template<typename T1, typename T2>
void operator()(T1 const&, T2 const&) const
{
// comparing two different types!
REQUIRE(false);
}
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(geometry_empty const&, geometry_empty const&) const
{
REQUIRE(true);
}
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(point<T> const& p1, point<T> const& p2) const
{
REQUIRE(p1.x == Approx(p2.x));
REQUIRE(p1.y == Approx(p2.y));
}
2015-04-10 14:17:36 +02:00
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(std::vector<point<T>> const& ls1, std::vector<point<T>> const& ls2) const
{
if (ls1.size() != ls2.size())
{
REQUIRE(false);
}
for (auto const p : zip_crange(ls1, ls2))
{
2015-04-10 14:17:36 +02:00
REQUIRE(p.template get<0>().x == Approx(p.template get<1>().x));
REQUIRE(p.template get<0>().y == Approx(p.template get<1>().y));
}
}
2015-04-10 14:17:36 +02:00
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(polygon<T> const& p1, polygon<T> const& p2) const
{
if (p1.size() != p2.size())
{
REQUIRE(false);
}
for (auto const p : zip_crange(p1, p2))
{
(*this)(static_cast<std::vector<point<T>> const&>(p.template get<0>()),
static_cast<std::vector<point<T>> const&>(p.template get<1>()));
}
}
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(line_string<T> const& ls1, line_string<T> const& ls2) const
{
2022-01-26 23:25:53 +01:00
(*this)(static_cast<std::vector<point<T>> const&>(ls1), static_cast<std::vector<point<T>> const&>(ls2));
}
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(multi_point<T> const& mp1, multi_point<T> const& mp2) const
{
2022-01-26 23:25:53 +01:00
(*this)(static_cast<std::vector<point<T>> const&>(mp1), static_cast<std::vector<point<T>> const&>(mp2));
}
2015-04-10 14:17:36 +02:00
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(multi_line_string<T> const& mls1, multi_line_string<T> const& mls2) const
{
if (mls1.size() != mls2.size())
{
REQUIRE(false);
}
for (auto const ls : zip_crange(mls1, mls2))
{
2022-01-26 23:25:53 +01:00
(*this)(ls.template get<0>(), ls.template get<1>());
}
}
2015-04-10 14:17:36 +02:00
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(multi_polygon<T> const& mpoly1, multi_polygon<T> const& mpoly2) const
{
if (mpoly1.size() != mpoly2.size())
{
REQUIRE(false);
}
for (auto const poly : zip_crange(mpoly1, mpoly2))
{
2022-01-26 23:25:53 +01:00
(*this)(poly.template get<0>(), poly.template get<1>());
}
}
2015-04-10 14:17:36 +02:00
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(mapnik::util::recursive_wrapper<geometry_collection<T>> const& c1_,
mapnik::util::recursive_wrapper<geometry_collection<T>> const& c2_) const
{
2015-04-09 22:22:51 +02:00
geometry_collection<T> const& c1 = static_cast<geometry_collection<T> const&>(c1_);
geometry_collection<T> const& c2 = static_cast<geometry_collection<T> const&>(c2_);
if (c1.size() != c2.size())
{
REQUIRE(false);
}
for (auto const g : zip_crange(c1, c2))
{
2022-01-26 23:25:53 +01:00
assert_g_equal(g.template get<0>(), g.template get<1>());
}
}
2015-04-10 14:17:36 +02:00
2022-01-26 23:25:53 +01:00
template<typename T>
void operator()(geometry_collection<T> const& c1, geometry_collection<T> const& c2) const
{
if (c1.size() != c2.size())
{
REQUIRE(false);
}
for (auto const g : zip_crange(c1, c2))
{
2022-01-26 23:25:53 +01:00
assert_g_equal(g.template get<0>(), g.template get<1>());
}
}
};
2022-01-26 23:25:53 +01:00
template<typename T>
2015-04-09 22:22:51 +02:00
void assert_g_equal(geometry<T> const& g1, geometry<T> const& g2)
{
return mapnik::util::apply_visitor(geometry_equal_visitor(), g1, g2);
}
2022-01-26 23:25:53 +01:00
template<typename T>
void assert_g_equal(T const& g1, T const& g2)
{
2022-01-26 23:25:53 +01:00
return geometry_equal_visitor()(g1, g2);
}
#endif // MAPNIK_UNIT_GEOMETRY_EQUAL