From 1847ce581d84e88d9143fb3e7584b3032406ca3b Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 3 May 2013 11:41:43 +0100 Subject: [PATCH] box2d + re-implement from_string avoiding tokenizer (~10x faster) --- include/mapnik/box2d.hpp | 2 +- src/box2d.cpp | 76 ++++++++++++++-------------------------- 2 files changed, 27 insertions(+), 51 deletions(-) diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp index 41909e677..128828f78 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/box2d.hpp @@ -92,7 +92,7 @@ public: void init(T x0,T y0,T x1,T y1); void clip(const box2d_type &other); void pad(T padding); - bool from_string(std::string const& s); + bool from_string(std::string const& str); bool valid() const; // define some operators diff --git a/src/box2d.cpp b/src/box2d.cpp index 0b4ea60fa..2ed9c7aa9 100644 --- a/src/box2d.cpp +++ b/src/box2d.cpp @@ -28,12 +28,23 @@ #include // boost -#include +// fusion +#include +// spirit #include +#include // agg #include "agg_trans_affine.h" +BOOST_FUSION_ADAPT_TPL_ADT( + (T), + (mapnik::box2d)(T), + (T, T, obj.minx(), obj.set_minx(val)) + (T, T, obj.miny(), obj.set_miny(val)) + (T, T, obj.maxx(), obj.set_maxx(val)) + (T, T, obj.maxy(), obj.set_maxy(val))) + namespace mapnik { template @@ -58,11 +69,6 @@ box2d::box2d(const box2d &rhs) miny_(rhs.miny_), maxx_(rhs.maxx_), maxy_(rhs.maxy_) {} -// copy rather than init so dfl ctor (0,0,-1,-1) is not modified -// https://github.com/mapnik/mapnik/issues/749 -/*{ - init(rhs.minx_,rhs.miny_,rhs.maxx_,rhs.maxy_); - }*/ template box2d::box2d(box2d_type const& rhs, const agg::trans_affine& tr) @@ -76,7 +82,7 @@ box2d::box2d(box2d_type const& rhs, const agg::trans_affine& tr) tr.transform(&x2, &y2); tr.transform(&x3, &y3); init(static_cast(x0), static_cast(y0), - static_cast(x2), static_cast(y2)); + static_cast(x2), static_cast(y2)); expand_to_include(static_cast(x1), static_cast(y1)); expand_to_include(static_cast(x3), static_cast(y3)); } @@ -381,49 +387,19 @@ void box2d::pad(T padding) maxy_ += padding; } + template -#if !defined(__SUNPRO_CC) -inline -#endif -bool box2d::from_string(std::string const& s) +inline bool box2d::from_string(std::string const& str) { - unsigned i = 0; - double d[4]; - bool success = false; - boost::char_separator sep(", "); - boost::tokenizer > tok(s, sep); - for (boost::tokenizer >::iterator beg = tok.begin(); - beg != tok.end(); ++beg) - { - std::string item = mapnik::util::trim_copy(*beg); - // note: we intentionally do not use mapnik::util::conversions::string2double - // here to ensure that shapeindex can statically compile mapnik::box2d without - // needing to link to libmapnik - std::string::const_iterator str_beg = item.begin(); - std::string::const_iterator str_end = item.end(); - bool r = boost::spirit::qi::phrase_parse(str_beg, - str_end, - boost::spirit::qi::double_, - boost::spirit::ascii::space, - d[i]); - if (!(r && (str_beg == str_end))) - { - break; - } - if (i == 3) - { - success = true; - break; - } - ++i; - } - - if (success) - { - init(static_cast(d[0]),static_cast(d[1]),static_cast(d[2]),static_cast(d[3])); - } - - return success; + using boost::spirit::qi::double_; + using boost::spirit::ascii::space; + bool r = boost::spirit::qi::phrase_parse(str.begin(), + str.end(), + double_ >> ',' >> double_ >> ',' + >> double_ >> ',' >> double_, + space, + *this); + return r; } template @@ -512,8 +488,8 @@ box2d& box2d::operator*=(agg::trans_affine const& tr) tr.transform(&x1, &y1); tr.transform(&x2, &y2); tr.transform(&x3, &y3); - init(static_cast(x0), static_cast(y0), - static_cast(x2), static_cast(y2)); + init(static_cast(x0), static_cast(y0), + static_cast(x2), static_cast(y2)); expand_to_include(static_cast(x1), static_cast(y1)); expand_to_include(static_cast(x3), static_cast(y3)); return *this;