for >= boost 1.45 (compile does not work with 1.42) move to karma for to_string conversions to avoid lexical cast - refs #1055

This commit is contained in:
Dane Springmeyer 2012-04-19 10:29:37 -07:00
parent f977134afd
commit 703d4ab7f2
2 changed files with 111 additions and 42 deletions

View file

@ -29,16 +29,73 @@
// stl
#include <string>
// boost
#include <boost/version.hpp>
#if BOOST_VERSION >= 104500
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/karma.hpp>
#else
#include <boost/lexical_cast.hpp>
#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 <typename T>
bool to_string(std::string & str, T value)
{
namespace karma = boost::spirit::karma;
std::back_insert_iterator<std::string> sink(str);
return karma::generate(sink, value);
}
template <typename T>
struct double_policy : boost::spirit::karma::real_policies<T>
{
typedef boost::spirit::karma::real_policies<T> 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, double_policy<double> > double_type;
std::back_insert_iterator<std::string> sink(str);
return karma::generate(sink, double_type(), value);
}
#else
template <typename T>
bool to_string(std::string & str, T value)
{
try
{
str = boost::lexical_cast<T>(value);
return true;
}
catch (std::exception const& ex)
{
return false;
}
}
#endif
}}

View file

@ -36,8 +36,6 @@
// stl
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
// uci
@ -338,20 +336,34 @@ struct add : public boost::static_visitor<V>
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 <typename R>
value_type operator() (UnicodeString const& lhs, R const& rhs) const
{
std::basic_ostringstream<char> 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 <typename L>
value_type operator() (L const& lhs , UnicodeString const& rhs) const
{
std::basic_ostringstream<char> 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 <typename T1, typename T2>
@ -540,14 +552,14 @@ struct to_bool : public boost::static_visitor<bool>
struct to_string : public boost::static_visitor<std::string>
{
template <typename T>
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>
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<UnicodeString>
template <typename T>
UnicodeString operator() (T val) const
{
std::basic_ostringstream<char> 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>
UnicodeString operator() (double val) const
{
std::basic_ostringstream<char> 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>
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>
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<double>
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