+ re-implement from_string avoiding tokenizer (~10x faster)
This commit is contained in:
artemp 2013-05-03 11:41:43 +01:00
parent 29f9273d3e
commit 1847ce581d
2 changed files with 27 additions and 51 deletions

View file

@ -92,7 +92,7 @@ public:
void init(T x0,T y0,T x1,T y1); void init(T x0,T y0,T x1,T y1);
void clip(const box2d_type &other); void clip(const box2d_type &other);
void pad(T padding); void pad(T padding);
bool from_string(std::string const& s); bool from_string(std::string const& str);
bool valid() const; bool valid() const;
// define some operators // define some operators

View file

@ -28,12 +28,23 @@
#include <stdexcept> #include <stdexcept>
// boost // boost
#include <boost/tokenizer.hpp> // fusion
#include <boost/fusion/include/adapt_adt.hpp>
// spirit
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_adapt_adt_attributes.hpp>
// agg // agg
#include "agg_trans_affine.h" #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 namespace mapnik
{ {
template <typename T> template <typename T>
@ -58,11 +69,6 @@ box2d<T>::box2d(const box2d &rhs)
miny_(rhs.miny_), miny_(rhs.miny_),
maxx_(rhs.maxx_), maxx_(rhs.maxx_),
maxy_(rhs.maxy_) {} 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 <typename T> template <typename T>
box2d<T>::box2d(box2d_type const& rhs, const agg::trans_affine& tr) box2d<T>::box2d(box2d_type const& rhs, const agg::trans_affine& tr)
@ -76,7 +82,7 @@ box2d<T>::box2d(box2d_type const& rhs, const agg::trans_affine& tr)
tr.transform(&x2, &y2); tr.transform(&x2, &y2);
tr.transform(&x3, &y3); tr.transform(&x3, &y3);
init(static_cast<T>(x0), static_cast<T>(y0), init(static_cast<T>(x0), static_cast<T>(y0),
static_cast<T>(x2), static_cast<T>(y2)); static_cast<T>(x2), static_cast<T>(y2));
expand_to_include(static_cast<T>(x1), static_cast<T>(y1)); expand_to_include(static_cast<T>(x1), static_cast<T>(y1));
expand_to_include(static_cast<T>(x3), static_cast<T>(y3)); expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
} }
@ -381,49 +387,19 @@ void box2d<T>::pad(T padding)
maxy_ += padding; maxy_ += padding;
} }
template <typename T> template <typename T>
#if !defined(__SUNPRO_CC) inline bool box2d<T>::from_string(std::string const& str)
inline
#endif
bool box2d<T>::from_string(std::string const& s)
{ {
unsigned i = 0; using boost::spirit::qi::double_;
double d[4]; using boost::spirit::ascii::space;
bool success = false; bool r = boost::spirit::qi::phrase_parse(str.begin(),
boost::char_separator<char> sep(", "); str.end(),
boost::tokenizer<boost::char_separator<char> > tok(s, sep); double_ >> ',' >> double_ >> ','
for (boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin(); >> double_ >> ',' >> double_,
beg != tok.end(); ++beg) space,
{ *this);
std::string item = mapnik::util::trim_copy(*beg); return r;
// 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<T>(d[0]),static_cast<T>(d[1]),static_cast<T>(d[2]),static_cast<T>(d[3]));
}
return success;
} }
template <typename T> template <typename T>
@ -512,8 +488,8 @@ box2d<T>& box2d<T>::operator*=(agg::trans_affine const& tr)
tr.transform(&x1, &y1); tr.transform(&x1, &y1);
tr.transform(&x2, &y2); tr.transform(&x2, &y2);
tr.transform(&x3, &y3); tr.transform(&x3, &y3);
init(static_cast<T>(x0), static_cast<T>(y0), init(static_cast<T>(x0), static_cast<T>(y0),
static_cast<T>(x2), static_cast<T>(y2)); static_cast<T>(x2), static_cast<T>(y2));
expand_to_include(static_cast<T>(x1), static_cast<T>(y1)); expand_to_include(static_cast<T>(x1), static_cast<T>(y1));
expand_to_include(static_cast<T>(x3), static_cast<T>(y3)); expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
return *this; return *this;