diff --git a/include/mapnik/util/conversions.hpp b/include/mapnik/util/conversions.hpp index 266b0f844..b79dd7dce 100644 --- a/include/mapnik/util/conversions.hpp +++ b/include/mapnik/util/conversions.hpp @@ -29,16 +29,73 @@ // stl #include +// boost +#include + +#if BOOST_VERSION >= 104500 +#include +#include +#else +#include +#endif + namespace mapnik { namespace util { - MAPNIK_DECL bool string2int(std::string const& value, int & result); - MAPNIK_DECL bool string2int(const char * value, int & result); +MAPNIK_DECL bool string2int(const char * value, int & result); +MAPNIK_DECL bool string2int(std::string const& value, int & result); - MAPNIK_DECL bool string2double(std::string const& value, double & result); - MAPNIK_DECL bool string2double(const char * value, double & result); +MAPNIK_DECL bool string2double(std::string const& value, double & result); +MAPNIK_DECL bool string2double(const char * value, double & result); - MAPNIK_DECL bool string2float(std::string const& value, float & result); - MAPNIK_DECL bool string2float(const char * value, float & result); +MAPNIK_DECL bool string2float(std::string const& value, float & result); +MAPNIK_DECL bool string2float(const char * value, float & result); + +#if BOOST_VERSION >= 104500 +// generic +template +bool to_string(std::string & str, T value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +template +struct double_policy : boost::spirit::karma::real_policies +{ + typedef boost::spirit::karma::real_policies base_type; + static int floatfield(T n) { return base_type::fmtflags::fixed; } + static unsigned precision(T n) { return 16 ;} +}; + + +// specialisation for double +template <> +inline bool to_string(std::string & str, double value) +{ + namespace karma = boost::spirit::karma; + typedef boost::spirit::karma::real_generator > double_type; + std::back_insert_iterator sink(str); + return karma::generate(sink, double_type(), value); +} + +#else + +template +bool to_string(std::string & str, T value) +{ + try + { + str = boost::lexical_cast(value); + return true; + } + catch (std::exception const& ex) + { + return false; + } +} + +#endif }} diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index a45d17c74..5db5b6d6a 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.hpp @@ -36,8 +36,6 @@ // stl #include #include -#include -#include #include // uci @@ -338,20 +336,34 @@ struct add : public boost::static_visitor return lhs + rhs; } + value_type operator() (UnicodeString const& lhs, value_null rhs) const + { + boost::ignore_unused_variable_warning(rhs); + return lhs; + } + + value_type operator() (value_null lhs, UnicodeString const& rhs) const + { + boost::ignore_unused_variable_warning(lhs); + return rhs; + } + template value_type operator() (UnicodeString const& lhs, R const& rhs) const { - std::basic_ostringstream out; - out << rhs; - return lhs + UnicodeString(out.str().c_str()); + std::string val; + if (util::to_string(val,rhs)) + return lhs + UnicodeString(val.c_str()); + return lhs; } template value_type operator() (L const& lhs , UnicodeString const& rhs) const { - std::basic_ostringstream out; - out << lhs; - return UnicodeString(out.str().c_str()) + rhs; + std::string val; + if (util::to_string(val,lhs)) + return UnicodeString(val.c_str()) + rhs; + return rhs; } template @@ -540,14 +552,14 @@ struct to_bool : public boost::static_visitor struct to_string : public boost::static_visitor { - template std::string operator() (T val) const { - std::stringstream ss; - ss << val; - return ss.str(); + std::string str; + util::to_string(str, val); + return str; } + // specializations std::string operator() (UnicodeString const& val) const { @@ -558,9 +570,9 @@ struct to_string : public boost::static_visitor std::string operator() (double val) const { - std::stringstream ss; - ss << std::setprecision(16) << val; - return ss.str(); + std::string str; + util::to_string(str, val); // TODO set precision(16) + return str; } std::string operator() (value_null const& val) const @@ -576,9 +588,9 @@ struct to_unicode : public boost::static_visitor template UnicodeString operator() (T val) const { - std::basic_ostringstream out; - out << val; - return UnicodeString(out.str().c_str()); + std::string str; + util::to_string(str,val); + return UnicodeString(str.c_str()); } // specializations @@ -589,9 +601,9 @@ struct to_unicode : public boost::static_visitor UnicodeString operator() (double val) const { - std::basic_ostringstream out; - out << std::setprecision(16) << val; - return UnicodeString(out.str().c_str()); + std::string str; + util::to_string(str,val); + return UnicodeString(str.c_str()); } UnicodeString operator() (value_null const& val) const @@ -612,9 +624,9 @@ struct to_expression_string : public boost::static_visitor std::string operator() (double val) const { - std::stringstream ss; - ss << std::setprecision(16) << val; - return ss.str(); + std::string output; + util::to_string(output,val); // TODO precision(16) + return output; } std::string operator() (bool val) const @@ -651,17 +663,17 @@ struct to_double : public boost::static_visitor double operator() (std::string const& val) const { - double ret(0); - mapnik::util::string2double(val,ret); - return ret; + double result; + if (util::string2double(val,result)) + return result; + return 0; } + double operator() (UnicodeString const& val) const { std::string utf8; to_utf8(val,utf8); - double ret(0); - mapnik::util::string2double(utf8,ret); - return ret; + return operator()(utf8); } double operator() (value_null const& val) const @@ -685,17 +697,17 @@ struct to_int : public boost::static_visitor int operator() (std::string const& val) const { - int ret(0); - mapnik::util::string2int(val,ret); - return ret; + int result; + if (util::string2int(val,result)) + return result; + return 0; } + int operator() (UnicodeString const& val) const { std::string utf8; to_utf8(val,utf8); - int ret(0); - mapnik::util::string2int(utf8,ret); - return ret; + return operator()(utf8); } int operator() (value_null const& val) const