[xpressive] capture float?

Hi all, I'm trying to capture a float with xpressive and put it into a local map. As a simplified example, I tried just pushing the matched pattern to a float and the result is always a float containing '0'. namespace xpr = boost::xpressive; std::map<float, std::string> l_floatOperMap; xpr::sregex l_relation = xpr::as_xpr("<=") | ">=" | "<" | ">"); l_floatRestriction = !(xpr::s1 = l_relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [xpr::ref(l_floatOperMap)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1)]; However, when I go to print the contents of l_floatOperMap, it contains only the tuple (0, ""). Is it something I'm doing wrong? It seems like this should work to me. Thanks, Greg

On Wed, Jul 23, 2014 at 4:07 PM, Greg Rubino <bibil.thaysose@gmail.com> wrote:
Hi all,
I'm trying to capture a float with xpressive and put it into a local map. As a simplified example, I tried just pushing the matched pattern to a float and the result is always a float containing '0'.
namespace xpr = boost::xpressive;
std::map<float, std::string> l_floatOperMap;
xpr::sregex l_relation = xpr::as_xpr("<=") | ">=" | "<" | ">"); l_floatRestriction = !(xpr::s1 = l_relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [xpr::ref(l_floatOperMap)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1)];
However, when I go to print the contents of l_floatOperMap, it contains only the tuple (0, ""). Is it something I'm doing wrong? It seems like this should work to me.
I neglected to mention that I am actually doing the very same thing with uint32_t and it works fine. Thanks, Greg

On 7/23/2014 3:47 PM, Greg Rubino wrote:
On Wed, Jul 23, 2014 at 4:07 PM, Greg Rubino wrote:
Hi all,
I'm trying to capture a float with xpressive and put it into a local map. As a simplified example, I tried just pushing the matched pattern to a float and the result is always a float containing '0'.
namespace xpr = boost::xpressive;
std::map<float, std::string> l_floatOperMap;
xpr::sregex l_relation = xpr::as_xpr("<=") | ">=" | "<" | ">"); l_floatRestriction = !(xpr::s1 = l_relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [xpr::ref(l_floatOperMap)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1)];
However, when I go to print the contents of l_floatOperMap, it contains only the tuple (0, ""). Is it something I'm doing wrong? It seems like this should work to me.
I neglected to mention that I am actually doing the very same thing with uint32_t and it works fine.
Works for me. This program: #include <map> #include <iostream> #include <boost/xpressive/xpressive.hpp> #include <boost/xpressive/regex_actions.hpp> int main() { namespace xpr = boost::xpressive; std::map<float, std::string> l_floatOperMap; xpr::sregex l_relation = xpr::as_xpr("<=") | ">=" | "<" | ">"; xpr::sregex l_floatRestriction = !(xpr::s1 = l_relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [ xpr::ref(l_floatOperMap)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1) ]; std::string str = ">3.14"; if(xpr::regex_match(str, l_floatRestriction)) { for(auto p : l_floatOperMap) { std::cout << "(" << p.first << ", " << p.second << ")" << std::endl; } } } Gives me this expected output: (3.14, >) Maybe you could send a complete repro? Thanks, Eric

Hi Eric, Thanks for getting back to me. I'm pretty sure this must have something to do with my Boost version (1.49.0). Comments below. On Wed, Jul 23, 2014 at 5:57 PM, Eric Niebler <eniebler@boost.org> wrote:
On 7/23/2014 3:47 PM, Greg Rubino wrote:
On Wed, Jul 23, 2014 at 4:07 PM, Greg Rubino wrote:
Hi all,
I'm trying to capture a float with xpressive and put it into a local map. As a simplified example, I tried just pushing the matched pattern to a float and the result is always a float containing '0'.
namespace xpr = boost::xpressive;
std::map<float, std::string> l_floatOperMap;
xpr::sregex l_relation = xpr::as_xpr("<=") | ">=" | "<" | ">"); l_floatRestriction = !(xpr::s1 = l_relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [xpr::ref(l_floatOperMap)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1)];
However, when I go to print the contents of l_floatOperMap, it contains only the tuple (0, ""). Is it something I'm doing wrong? It seems like this should work to me.
I neglected to mention that I am actually doing the very same thing with uint32_t and it works fine.
Works for me. This program:
#include <map> #include <iostream> #include <boost/xpressive/xpressive.hpp> #include <boost/xpressive/regex_actions.hpp>
int main() { namespace xpr = boost::xpressive;
std::map<float, std::string> l_floatOperMap;
How did you get away with no #include<string>?
xpr::sregex l_relation = xpr::as_xpr("<=") | ">=" | "<" | ">"; xpr::sregex l_floatRestriction = !(xpr::s1 = l_relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [ xpr::ref(l_floatOperMap)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1) ];
std::string str = ">3.14";
if(xpr::regex_match(str, l_floatRestriction)) { for(auto p : l_floatOperMap)
I'm using c++03, so I have no auto :(
{ std::cout << "(" << p.first << ", " << p.second << ")" << std::endl; } } }
Gives me this expected output:
(3.14, >)
When I compile with gcc 4.8 and Boost 1.55 at home I get the same result, although my program looks more like this: #include <map> #include <string> #include <iostream> #include <boost/foreach.hpp> #include <boost/xpressive/xpressive.hpp> #include <boost/xpressive/regex_actions.hpp> namespace xpr = boost::xpressive; int main(int argc, char** argv) { typedef std::map<float, std::string> float_oper_map; typedef std::map<unsigned int, std::string> uint_oper_map; float_oper_map float_map; uint_oper_map uint_map; xpr::sregex relation = xpr::as_xpr("<=") | ">=" | "<" | ">"; xpr::sregex float_restrict = !(xpr::s1 = relation) >> (xpr::s2 = (+xpr::_d >> '.' >> +xpr::_d)) [ xpr::ref(float_map)[xpr::as<float>(xpr::s2)] = xpr::as<std::string>(xpr::s1) ]; xpr::sregex uint_restrict = !(xpr::s1 = relation) >> (xpr::s2 = +xpr::_d) [ xpr::ref(uint_map)[xpr::as<unsigned int>(xpr::s2)] = xpr::as<std::string>(xpr::s1) ]; xpr::sregex expression = uint_restrict | float_restrict; std::string float_str = ">3.14"; std::string uint_str = ">3"; if(xpr::regex_match(float_str, expression)) { BOOST_FOREACH(const float_oper_map::value_type& val, float_map) { std::cout << '(' << val.first << ',' << val.second << ')' << std::endl; } } if(xpr::regex_match(uint_str, expression)) { BOOST_FOREACH(const uint_oper_map::value_type& val, uint_map) { std::cout << '(' << val.first << ',' << val.second << ')' << std::endl; } } return 0; } // END I'm going to try with Boost 1.49 and see if I get different results. If anything interesting happens, I'll get back on this thread. I should definitely be able to come up with a full repro tomorrow. Thanks again! Greg
participants (2)
-
Eric Niebler
-
Greg Rubino