remove wkt_generator_grammar_int to minimise code duplication

remove redundant template parameter - we can deduce coord_type from Geometry
add coord generator traits to control generator instantiation at compile time
This commit is contained in:
artemp 2015-06-10 11:10:17 +01:00
parent 89d258743a
commit 8e30a89522
4 changed files with 40 additions and 139 deletions

View file

@ -35,7 +35,7 @@ namespace mapnik { namespace util {
inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry<double> const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<double>, double > generator;
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<double>> generator;
sink_type sink(wkt);
return boost::spirit::karma::generate(sink, generator, geom);
}
@ -43,7 +43,7 @@ inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry<double> const&
inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry<std::int64_t> const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
static const mapnik::wkt::wkt_generator_grammar_int<sink_type, mapnik::geometry::geometry<std::int64_t>, std::int64_t > generator;
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<std::int64_t>> generator;
sink_type sink(wkt);
return boost::spirit::karma::generate(sink, generator, geom);
}

View file

@ -86,66 +86,52 @@ struct wkt_coordinate_policy : karma::real_policies<T>
}
};
template <typename T>
struct coordinate_generator;
template <>
struct coordinate_generator<double>
{
using generator = karma::real_generator<double, detail::wkt_coordinate_policy<double> >;
};
template <>
struct coordinate_generator<std::int64_t>
{
using generator = karma::int_generator<std::int64_t>;
};
}
template <typename OutputIterator, typename Geometry, typename T>
template <typename OutputIterator, typename Geometry>
struct wkt_generator_grammar :
karma::grammar<OutputIterator, Geometry const& ()>
{
using coord_type = typename Geometry::value_type;
wkt_generator_grammar();
// rules
karma::rule<OutputIterator, Geometry const&()> geometry;
karma::rule<OutputIterator, karma::locals<mapnik::geometry::geometry_types>, Geometry const&() > geometry_dispatch;
karma::rule<OutputIterator, geometry::geometry<T> const&()> point;
karma::rule<OutputIterator, geometry::point<T> const&()> point_coord;
karma::rule<OutputIterator, geometry::geometry<T> const&()> linestring;
karma::rule<OutputIterator, geometry::line_string<T> const&()> linestring_coord;
karma::rule<OutputIterator, geometry::geometry<T> const&()> polygon;
karma::rule<OutputIterator, geometry::polygon<T> const&()> polygon_coord;
karma::rule<OutputIterator, geometry::linear_ring<T> const&()> exterior_ring_coord;
karma::rule<OutputIterator, std::vector<geometry::linear_ring<T> > const&()> interior_ring_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> multi_point;
karma::rule<OutputIterator, geometry::multi_point<T> const& ()> multi_point_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> multi_linestring;
karma::rule<OutputIterator, geometry::multi_line_string<T> const& ()> multi_linestring_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> multi_polygon;
karma::rule<OutputIterator, geometry::multi_polygon<T> const& ()> multi_polygon_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> geometry_collection;
karma::rule<OutputIterator, geometry::geometry_collection<T> const& ()> geometries;
karma::rule<OutputIterator, geometry::geometry<coord_type> const&()> point;
karma::rule<OutputIterator, geometry::point<coord_type> const&()> point_coord;
karma::rule<OutputIterator, geometry::geometry<coord_type> const&()> linestring;
karma::rule<OutputIterator, geometry::line_string<coord_type> const&()> linestring_coord;
karma::rule<OutputIterator, geometry::geometry<coord_type> const&()> polygon;
karma::rule<OutputIterator, geometry::polygon<coord_type> const&()> polygon_coord;
karma::rule<OutputIterator, geometry::linear_ring<coord_type> const&()> exterior_ring_coord;
karma::rule<OutputIterator, std::vector<geometry::linear_ring<coord_type> > const&()> interior_ring_coord;
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> multi_point;
karma::rule<OutputIterator, geometry::multi_point<coord_type> const& ()> multi_point_coord;
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> multi_linestring;
karma::rule<OutputIterator, geometry::multi_line_string<coord_type> const& ()> multi_linestring_coord;
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> multi_polygon;
karma::rule<OutputIterator, geometry::multi_polygon<coord_type> const& ()> multi_polygon_coord;
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> geometry_collection;
karma::rule<OutputIterator, geometry::geometry_collection<coord_type> const& ()> geometries;
boost::phoenix::function<detail::get_type<Geometry> > geometry_type;
karma::symbols<mapnik::geometry::geometry_types, char const*> empty;
//
karma::real_generator<T, detail::wkt_coordinate_policy<T> > coordinate;
};
template <typename OutputIterator, typename Geometry, typename T>
struct wkt_generator_grammar_int :
karma::grammar<OutputIterator, Geometry const& ()>
{
wkt_generator_grammar_int();
// rules
karma::rule<OutputIterator, Geometry const&()> geometry;
karma::rule<OutputIterator, karma::locals<mapnik::geometry::geometry_types>, Geometry const&() > geometry_dispatch;
karma::rule<OutputIterator, geometry::geometry<T> const&()> point;
karma::rule<OutputIterator, geometry::point<T> const&()> point_coord;
karma::rule<OutputIterator, geometry::geometry<T> const&()> linestring;
karma::rule<OutputIterator, geometry::line_string<T> const&()> linestring_coord;
karma::rule<OutputIterator, geometry::geometry<T> const&()> polygon;
karma::rule<OutputIterator, geometry::polygon<T> const&()> polygon_coord;
karma::rule<OutputIterator, geometry::linear_ring<T> const&()> exterior_ring_coord;
karma::rule<OutputIterator, std::vector<geometry::linear_ring<T> > const&()> interior_ring_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> multi_point;
karma::rule<OutputIterator, geometry::multi_point<T> const& ()> multi_point_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> multi_linestring;
karma::rule<OutputIterator, geometry::multi_line_string<T> const& ()> multi_linestring_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> multi_polygon;
karma::rule<OutputIterator, geometry::multi_polygon<T> const& ()> multi_polygon_coord;
karma::rule<OutputIterator, geometry::geometry<T> const& ()> geometry_collection;
karma::rule<OutputIterator, geometry::geometry_collection<T> const& ()> geometries;
boost::phoenix::function<detail::get_type<Geometry> > geometry_type;
karma::symbols<mapnik::geometry::geometry_types, char const*> empty;
//
karma::int_generator<T> coordinate;
typename detail::coordinate_generator<coord_type>::generator coordinate;
};
}}

View file

@ -28,8 +28,8 @@
namespace mapnik { namespace wkt {
template <typename OutputIterator, typename Geometry, typename T>
wkt_generator_grammar<OutputIterator, Geometry,T>::wkt_generator_grammar()
template <typename OutputIterator, typename Geometry>
wkt_generator_grammar<OutputIterator, Geometry>::wkt_generator_grammar()
: wkt_generator_grammar::base_type(geometry)
{
boost::spirit::karma::_val_type _val;
@ -113,89 +113,4 @@ wkt_generator_grammar<OutputIterator, Geometry,T>::wkt_generator_grammar()
}
template <typename OutputIterator, typename Geometry, typename T>
wkt_generator_grammar_int<OutputIterator, Geometry,T>::wkt_generator_grammar_int()
: wkt_generator_grammar_int::base_type(geometry)
{
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::uint_type uint_;
boost::spirit::karma::eps_type eps;
empty.add
(geometry::geometry_types::Point, "POINT EMPTY")
(geometry::geometry_types::LineString, "LINESTRING EMPTY")
(geometry::geometry_types::Polygon, "POLYGON EMPTY")
(geometry::geometry_types::MultiPoint, "MULTIPOINT EMPTY")
(geometry::geometry_types::MultiLineString, "MULTILINESTRING EMPTY")
(geometry::geometry_types::MultiPolygon, "MULTIPOLYGON EMPTY")
(geometry::geometry_types::GeometryCollection, "GEOMETRYCOLLECTION EMPTY")
;
geometry = geometry_dispatch.alias()
;
geometry_dispatch = eps[_a = geometry_type(_val)] <<
(&uint_(geometry::geometry_types::Point)[_1 = _a]
<< point)
|
(&uint_(geometry::geometry_types::LineString)[_1 = _a]
<< (linestring | empty[_1 = _a]))
|
(&uint_(geometry::geometry_types::Polygon)[_1 = _a]
<< (polygon | empty[_1 = _a]))
|
(&uint_(geometry::geometry_types::MultiPoint)[_1 = _a]
<< ( multi_point | empty[_1 = _a]))
|
(&uint_(geometry::geometry_types::MultiLineString)[_1 = _a]
<< (multi_linestring | empty[_1 = _a]))
|
(&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a]
<< (multi_polygon | empty[_1 = _a]))
|
(&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a]
<< (geometry_collection | empty[_1 = _a]))
|
(&uint_(geometry::geometry_types::Unknown)[_1 = _a]
<< lit("POINT EMPTY")) // special case for geometry_empty as mapnik::geometry::point<double> can't be empty
;
point = lit("POINT(") << point_coord << lit(")")
;
linestring = lit("LINESTRING(") << linestring_coord << lit(")")
;
polygon = lit("POLYGON(") << polygon_coord << lit(")")
;
multi_point = lit("MULTIPOINT(") << multi_point_coord << lit(")")
;
multi_linestring = lit("MULTILINESTRING(") << multi_linestring_coord << lit(")")
;
multi_polygon = lit("MULTIPOLYGON(") << multi_polygon_coord << lit(")")
;
geometry_collection = lit("GEOMETRYCOLLECTION(") << geometries << lit(")")
;
point_coord = coordinate << lit(' ') << coordinate
;
linestring_coord = point_coord % lit(',')
;
polygon_coord = lit('(') << exterior_ring_coord << lit(')') << interior_ring_coord
;
exterior_ring_coord = linestring_coord.alias()
;
interior_ring_coord = *(lit(",(") << exterior_ring_coord << lit(')'))
;
multi_point_coord = linestring_coord.alias()
;
multi_linestring_coord = (lit('(') << linestring_coord << lit(')')) % lit(',')
;
multi_polygon_coord = (lit('(') << polygon_coord << lit(')')) % lit(',')
;
geometries = geometry % lit(',')
;
}
}}

View file

@ -27,7 +27,7 @@
namespace mapnik { namespace wkt {
using sink_type = std::back_insert_iterator<std::string>;
template struct wkt_generator_grammar<sink_type, mapnik::geometry::geometry<double>, double >;
template struct wkt_generator_grammar_int<sink_type, mapnik::geometry::geometry<std::int64_t>, std::int64_t >;
template struct wkt_generator_grammar<sink_type, mapnik::geometry::geometry<double>>;
template struct wkt_generator_grammar<sink_type, mapnik::geometry::geometry<std::int64_t>>;
}}