Hi!
If performance matters, you might want to avoid xpressive::as. It's just
a thin wrapper over boost::lexical_cast, which may(?) do dynamic
allocation while performing conversion. Try this, which uses a wrapper
over std::atoi instead. (It's a bit sneaky in that it uses the fact that
characters in a string are guaranteed contiguous, and that atoi stops
parsing on the first non-digit.)
Disclaimer: this code is not well-tested.
struct asint_ : std::unary_function<xp::ssub_match, int>
{
int operator()(xp::ssub_match const &s) const
{
return (int)std::atoi(&*s.first);
}
};
xp::function<asint_>::type const asint = {};
(+_d)[result = asint(_)] >>
int main()
{
using namespace xp;
placeholder<double> result;
sregex double_ = ~after(_d) >>
// a number with no group separators, and either a period or comma
// for fraction separator
!((set=',','.') >> (_d >> _d)[result += asint(_)/100.0]) >>
~before(set[_d|','|'.'])!('.' >> (_d >> _d)[result += asint(_)/100.0]) >>
// A number with optional group separators
| repeat<1,3>(_d)[result = asint(_)] >>
(
// ... with comma group separators and period fraction separator
*(',' >> repeat<3>(_d)[result *= 1000, result += asint(_)]) >>
~before(set[_d|','|'.'])!(',' >> (_d >> _d)[result += asint(_)/100.0]) >>
// ... with period group separators and comma fraction separator
| *('.' >> repeat<3>(_d)[result *= 1000, result += asint(_)]) >>
~before(set[_d|','|'.'])
);
std::string str;
double d = 0.0;
smatch what;
what.let(result = d);
std::cout << std::fixed << std::setprecision(2);
while (std::getline(std::cin, str))
{
if (regex_search(str, what, double_))
{
std::cout << "Double = " << d << '\n';
}
else
{
std::cout << "No match\n";
}
}
}
On 9/9/2011 5:26 AM, Jens Saathoff wrote:> 2011/9/9 Eric Niebler <eric@boostpro.com <mailto:eric@boostpro.com>>
> Perfect! That works!
>
> I will compare it with my thousand-sep rule/grammar in boost::spirit, a
> little benchmark to find out which one is faster. Do have
> experiences/results with boost::spirit vs. boost::xpressive?
>
>
> Thank you very much. Have a nice weekend.
>
>
> #include <string>
> #include <iostream>
> #include <iomanip>
> #include <boost/xpressive/xpressive_static.hpp>
> #include <boost/xpressive/regex_actions.hpp>
> namespace xp = boost::xpressive;
>
> int main()
> {
> using namespace xp;
> placeholder<double> result;
> sregex double_ = ~after(_d) >>
> // a number with no group separators, and either a period or
> comma
> // for fraction separator
> (+_d)[result = as<double>(_)] >>
> !((set=',','.') >> (_d >> _d)[result += as<int>(_)/100.0]) >>
> ~before(set[_d|','|'.'])
> // A number with optional group separators
> | repeat<1,3>(_d)[result = as<int>(_)] >>
> (
> // ... with comma group separators and period fraction
> separator
> *(',' >> repeat<3>(_d)[result *= 1000, result +=
> as<int>(_)]) >>
> !('.' >> (_d >> _d)[result += as<int>(_)/100.0]) >>
> ~before(set[_d|','|'.'])
> // ... with period group separators and comma fraction
> separator
> | *('.' >> repeat<3>(_d)[result *= 1000, result +=
> as<int>(_)]) >>
> !(',' >> (_d >> _d)[result += as<int>(_)/100.0]) >>
> ~before(set[_d|','|'.'])
> );
>
> std::string str;
> double d = 0.0;
> smatch what;
> what.let(result = d);
> std::cout << std::fixed << std::setprecision(2);
> while (std::getline(std::cin, str))
> {
> if (regex_search(str, what, double_))
> {
> std::cout << "Double = " << d << '\n';
> }
> else
> {
> std::cout << "No match\n";
> }
> }
> }
>
>
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users@lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
--
Eric Niebler
BoostPro Computing
http://www.boostpro.com
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users