Boost C++ Libraries: Ticket #3999: multi_pass cannot deal with all input iterators https://svn.boost.org/trac10/ticket/3999 <p> multi_pass has trouble with various input iterators. </p> <p> First, Microsoft's istreambuf_iterator, because it doesn't implement DR445, reports its reference as Char&amp;, but its operator* returns Char. This causes compilation errors all over the place. </p> <p> Second, a standards-conformant istreambuf_iterator post-DR445 (i.e. C++0x) has both operator* return type and reference as Char. This compiles but is unsafe because InputPolicy::get_value is specified to return a const Value&amp;, and this reference binds to the temporary returned by operator*. InputPolicy::get_value should return MultiPass::reference. This would also make the Value template parameter to this function superfluous. </p> <p> Doing this change allows Spirit to compile with my own istreambuf_iterator replacement. I have no idea what to do about Microsoft's istreambuf_iterator, though. A workaround for that problem would be nice, since using istreambuf_iterator is far preferable over using istream_iterator, since the latter is subject to the skipws flag and thus easily leads to hard-to-find bugs. (By the way, the documentation should prominently mention the danger of skipws.) </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3999 Trac 1.4.3 Joel de Guzman Thu, 11 Mar 2010 22:47:34 GMT owner changed https://svn.boost.org/trac10/ticket/3999#comment:1 https://svn.boost.org/trac10/ticket/3999#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Joel de Guzman</span> to <span class="trac-author">Hartmut Kaiser</span> </li> </ul> Ticket Hartmut Kaiser Fri, 12 Mar 2010 02:18:25 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3999#comment:2 https://svn.boost.org/trac10/ticket/3999#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/60496" title="Spirit: fixed #3999: ">[60496]</a>) Spirit: fixed <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3999" title="#3999: Bugs: multi_pass cannot deal with all input iterators (closed: fixed)">#3999</a>: </p> Ticket anonymous Fri, 12 Mar 2010 02:24:52 GMT <link>https://svn.boost.org/trac10/ticket/3999#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:3</guid> <description> <p> The commit mention above fixes the return value issue. Thanks for pointing this out! </p> <p> The problem with Microsofts istreambuf_iterator has already been discussed on Spirit's mailing list. So I recently added a new input policy: buffering_input_iterator which is buffering the last character it got from the underlying iterator, which allows to return a refernce from multi_pass' operator*() in this case as well. This new policy is now the default input policy when using make_multi_pass(). It's a bit less efficient than the input_iterator policy, but helps to overcome the problem you described. </p> <p> Regards Hartmut </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Mon, 10 Jun 2013 06:02:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3999#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:4</guid> <description> <p> I'm not sure this bug should be considered fixed. <code>multi_pass</code> claims to make any valid underlying input iterator into a forward iterator, does it not? Shouldn't it select the right policy automatically? I have the same problem with clang's istreambuf_iterator in C++11 mode. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Mon, 10 Jun 2013 06:18:02 GMT</pubDate> <title>status changed; resolution deleted https://svn.boost.org/trac10/ticket/3999#comment:5 https://svn.boost.org/trac10/ticket/3999#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> In fact, under Clang with C++11, this program fails to compile: </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;utility&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/spirit/home/support/multi_pass.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;iterator&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/mpl/assert.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/type_traits/is_reference.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/type_traits/is_same.hpp&gt;</span><span class="cp"></span> <span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">spirit</span><span class="o">::</span><span class="n">multi_pass</span><span class="o">&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">istreambuf_iterator</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">spirit</span><span class="o">::</span><span class="n">iterator_policies</span><span class="o">::</span><span class="n">default_policy</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">spirit</span><span class="o">::</span><span class="n">iterator_policies</span><span class="o">::</span><span class="n">first_owner</span> <span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">spirit</span><span class="o">::</span><span class="n">iterator_policies</span><span class="o">::</span><span class="n">ref_counted</span> <span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">spirit</span><span class="o">::</span><span class="n">iterator_policies</span><span class="o">::</span><span class="n">buffering_input_iterator</span> <span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">iterator</span><span class="p">;</span> <span class="n">BOOST_MPL_ASSERT</span><span class="p">((</span> <span class="n">boost</span><span class="o">::</span><span class="n">is_same</span><span class="o">&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;::</span><span class="n">iterator_category</span> <span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">forward_iterator_tag</span><span class="o">&gt;</span> <span class="p">));</span> <span class="n">BOOST_MPL_ASSERT</span><span class="p">((</span> <span class="n">boost</span><span class="o">::</span><span class="n">is_reference</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;::</span><span class="n">reference</span><span class="o">&gt;</span> <span class="p">));</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{}</span> </pre></div></div> Ticket Dave Abrahams Mon, 10 Jun 2013 06:27:43 GMT <link>https://svn.boost.org/trac10/ticket/3999#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:6</guid> <description> <p> …and I think this simple patch fixes it. Hopefully someone can check my reasoning </p> <div class="wiki-code"> <div class="diff"> <ul class="entries"> <li class="entry"> <h2> <a>buffering_input_iterator_policy.hpp</a> </h2> <table class="trac-diff inline" cellspacing="0"> <colgroup> <col class="lineno"/><col class="lineno"/><col class="content"/> </colgroup> <thead> <tr> <th title="File buffering_input_iterator_policy.hpp 2013-06-09 20:34:46.000000000 -0700"> old </th> <th title="File /Users/dave/src/boost/release/boost_1_53_0/boost/spirit/home/support/iterators/detail/buffering_input_iterator_policy.hpp 2013-06-09 23:22:02.000000000 -0700"> new </th> <td> <em></em> &nbsp; </td> </tr> </thead> <tbody class="unmod"> <tr> <th>49</th><th>49</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typename boost::detail::iterator_traits&lt;T&gt;::pointer</span></td> </tr> <tr> <th>50</th><th>50</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pointer;</span></td> </tr> <tr> <th>51</th><th>51</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typedef</span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>52</th><th>&nbsp;</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <del>typename boost::detail::iterator_traits&lt;T&gt;::reference</del></span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>52</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ins>result_type&amp;</ins></span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>53</th><th>53</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reference;</span></td> </tr> <tr> <th>54</th><th>54</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typedef result_type value_type;</span></td> </tr> <tr> <th>55</th><th>55</th><td class="l"><span></span></td> </tr> </tbody> </table> </li> </ul> </div></div> </description> <category>Ticket</category> </item> <item> <dc:creator>Hartmut Kaiser</dc:creator> <pubDate>Mon, 10 Jun 2013 12:46:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3999#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:7</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3999#comment:6" title="Comment 6">dave</a>: </p> <blockquote class="citation"> <p> …and I think this simple patch fixes it. Hopefully someone can check my reasoning </p> <div class="wiki-code"> <div class="diff"> <ul class="entries"> <li class="entry"> <h2> <a>buffering_input_iterator_policy.hpp</a> </h2> <table class="trac-diff inline" cellspacing="0"> <colgroup> <col class="lineno"/><col class="lineno"/><col class="content"/> </colgroup> <thead> <tr> <th title="File buffering_input_iterator_policy.hpp 2013-06-09 20:34:46.000000000 -0700"> old </th> <th title="File /Users/dave/src/boost/release/boost_1_53_0/boost/spirit/home/support/iterators/detail/buffering_input_iterator_policy.hpp 2013-06-09 23:22:02.000000000 -0700"> new </th> <td> <em></em> &nbsp; </td> </tr> </thead> <tbody class="unmod"> <tr> <th>49</th><th>49</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typename boost::detail::iterator_traits&lt;T&gt;::pointer</span></td> </tr> <tr> <th>50</th><th>50</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pointer;</span></td> </tr> <tr> <th>51</th><th>51</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typedef</span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>52</th><th>&nbsp;</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <del>typename boost::detail::iterator_traits&lt;T&gt;::reference</del></span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>52</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ins>result_type&amp;</ins></span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>53</th><th>53</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reference;</span></td> </tr> <tr> <th>54</th><th>54</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typedef result_type value_type;</span></td> </tr> <tr> <th>55</th><th>55</th><td class="l"><span></span></td> </tr> </tbody> </table> </li> </ul> </div></div></blockquote> <p> Does this mean that in your case <code>result_type&amp;</code> is something different from <code>typename boost::detail::iterator_traits&lt;T&gt;::reference</code>? That does not look right to me. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Mon, 10 Jun 2013 15:39:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3999#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:8</guid> <description> <p> See the C++11 specification for <code>istreambuf_iterator&lt;char&gt;</code>. Note that result_type is just an implementation detail for this particular policy. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Thu, 11 Jul 2013 10:04:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3999#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:9</guid> <description> <p> I know everyone's busy, but it disturbs me that my my claim here is given so little credence, and when I offer a standard reference to prove my point, it isn't followed up on. I <em>am</em>, after all, an authority on the iterator requirements and an author of the Boost Iterator Library. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Hartmut Kaiser</dc:creator> <pubDate>Thu, 11 Jul 2013 11:51:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3999#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:10</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3999#comment:9" title="Comment 9">dave</a>: </p> <blockquote class="citation"> <p> I know everyone's busy, but it disturbs me that my my claim here is given so little credence, and when I offer a standard reference to prove my point, it isn't followed up on. I <em>am</em>, after all, an authority on the iterator requirements and an author of the Boost Iterator Library. </p> </blockquote> <p> Even if you're <em>the</em> authority, you'll have to cut me some slack while I'm travelling and on holidays. There are more important things than iterators after all. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Thu, 11 Jul 2013 14:58:43 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3999#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:11</guid> <description> <p> Fair enough; enjoy your break, Hartmut. BTW your <a class="wiki" href="https://svn.boost.org/trac10/wiki/BoostCon">BoostCon</a> talk is inspiring :-) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Hartmut Kaiser</dc:creator> <pubDate>Wed, 31 Jul 2013 15:23:14 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/3999#comment:12 https://svn.boost.org/trac10/ticket/3999#comment:12 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/85178" title="Spirit: fixed #3999: multi_pass cannot deal with all input iterators">[85178]</a>) Spirit: fixed <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3999" title="#3999: Bugs: multi_pass cannot deal with all input iterators (closed: fixed)">#3999</a>: multi_pass cannot deal with all input iterators </p> Ticket Dave Abrahams Fri, 09 Aug 2013 20:28:19 GMT <link>https://svn.boost.org/trac10/ticket/3999#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3999#comment:13</guid> <description> <p> Thanks! </p> </description> <category>Ticket</category> </item> </channel> </rss>