Re: [Boost-bugs] [Boost C++ Libraries] #2429: raw[] attribute incompatibility

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #2429: raw[] attribute incompatibility
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-06-02 01:32:48


#2429: raw[] attribute incompatibility
------------------------------------------+---------------------------------
  Reporter: vallentin_at_[hidden] | Owner: djowel
      Type: Bugs | Status: closed
 Milestone: Boost 1.37.0 | Component: spirit
   Version: Boost 1.36.0 | Severity: Problem
Resolution: invalid | Keywords: raw, attribute, compatibility
------------------------------------------+---------------------------------
Changes (by hkaiser):

  * status: new => closed
  * resolution: => invalid

Comment:

 Replying to [ticket:2429 vallentin_at_[hidden]]:
> I discovered an issue with the raw[] parser returning an
 iterator_range<T>.
> While it should be compatible to std::string, it is not according to my
> experience. Below, I attached an excerpt from the mailing list that
 captures the
> problem pretty well.
>
> On Tue, Oct 21, 2008 at 09:04:48AM +0800, Joel de Guzman wrote:
> > First, std::string should be compatible with iterator pair, so it
 should
> > just be:
> >
> > raw["foo"][_val = _1]
>
> This was in fact my first choice but did not compile with several g++
> versions [1]:

 This doesn't compile, and rightly so. _1 has the type iterator_range<> and
 _val has the type string. Since there is no assignment operator allowing
 to do this conversion, the compilation must fail. Everything ok so far.

> > Or simply:
> >
> > r %= raw["foo"];
>
> Unlike the explicit above version, this works. This primarily drives my
> confusion. However, in my more complex grammar I cannot use this
> convenient approach.

 This must compile (and as you've seen, it does). The reason is, that the
 raw[] directive is able to store it's attribute in any type 'compatible'
 compatible with an iterator_range<>. That means it can store it's
 attribute in any type having a similar constructor as iterator_range (or
 otherwise similar conversion operators). As string has a constructor
 taking two iterators (as iterator_range<> does) the code above compiles
 and works fine.

> > But, if you really need to get at the first/last, since
> boost::iterator_range
> > is a valid STL sequence, you can simply use:
> >
> > construct<std::string>(begin(_1),end(_1))
> >
> > begin and end are phoenix functions in the stl/container module.
>
> Interestingly replacing boost::phoenix::at_c<0>(_1) with begin(_1) /
> end(_1) works and compiles.

 Remember spirit::arg_names::_1 is not the same as phoenix::_1. I hope this
 answers your question.

 Regards Hartmut

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/2429#comment:1>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:00 UTC