reduce usage of boost::lexical_cast during map parsing by using spirit2-based conversion functions - refs #1055

This commit is contained in:
Dane Springmeyer 2012-02-24 18:26:48 -08:00
parent 2f134657b4
commit 954eb5c539
2 changed files with 70 additions and 15 deletions

View file

@ -27,11 +27,11 @@
#include <mapnik/enumeration.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/util/conversions.hpp>
// boost
#include <boost/property_tree/ptree.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <boost/lexical_cast.hpp>
// stl
#include <iostream>
@ -39,6 +39,9 @@
namespace mapnik {
template <typename T>
static boost::optional<T> fast_cast(std::string const& value);
template <typename T>
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute,
T const& default_value);
@ -205,6 +208,39 @@ struct name_trait< mapnik::enumeration<ENUM, MAX> >
}
};
template <typename T>
boost::optional<T> fast_cast(std::string const& value)
{
return boost::lexical_cast<T>( value );
}
template <>
boost::optional<int> fast_cast(std::string const& value)
{
int result;
if (mapnik::conversions::string2int(value,&result))
return boost::optional<int>(result);
return boost::optional<int>();
}
template <>
boost::optional<double> fast_cast(std::string const& value)
{
double result;
if (mapnik::conversions::string2double(value,&result))
return boost::optional<double>(result);
return boost::optional<double>();
}
template <>
boost::optional<float> fast_cast(std::string const& value)
{
float result;
if (mapnik::conversions::string2float(value,&result))
return boost::optional<float>(result);
return boost::optional<float>();
}
template <typename T>
T get(boost::property_tree::ptree const& node,
std::string const& name,
@ -223,11 +259,12 @@ T get(boost::property_tree::ptree const& node,
if ( str )
{
try
boost::optional<T> result = fast_cast<T>(*str);
if (result)
{
return boost::lexical_cast<T>( * str );
return *result;
}
catch (const boost::bad_lexical_cast & )
else
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
@ -296,11 +333,12 @@ T get(boost::property_tree::ptree const& node, std::string const& name, bool is_
(is_attribute ? "attribute " : "child node ") +
"'" + name + "' is missing");
}
try
boost::optional<T> result = fast_cast<T>(*str);
if (result)
{
return boost::lexical_cast<T>( *str );
return *result;
}
catch (const boost::bad_lexical_cast & )
else
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
@ -352,11 +390,8 @@ boost::optional<T> get_optional(boost::property_tree::ptree const& node, std::st
boost::optional<T> result;
if ( str )
{
try
{
result = boost::lexical_cast<T>( *str );
}
catch (const boost::bad_lexical_cast &)
result = fast_cast<T>(*str);
if (!result)
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
@ -388,7 +423,6 @@ inline boost::optional<color> get_optional(boost::property_tree::ptree const& no
{
try
{
//result = boost::lexical_cast<T>( *str );
result = mapnik::color_factory::from_string((*str).c_str());
}
catch (...)

View file

@ -69,7 +69,7 @@ static bool string2double(std::string const& value, double * result)
return r && (str_beg == str_end);
}
static bool string2int(const char * value, double * result)
static bool string2double(const char * value, double * result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
@ -81,6 +81,27 @@ static bool string2int(const char * value, double * result)
return r && (iter == end);
}
static bool string2float(std::string const& value, float * result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,qi::float_,ascii::space,*result);
return r && (str_beg == str_end);
}
static bool string2float(const char * value, float * result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *begin = value;
const char *iter = begin;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,qi::float_,ascii::space,*result);
return r && (iter == end);
}
}
}