Boost C++ Libraries: Ticket #5559: interval_set works not correct with custom compare function https://svn.boost.org/trac10/ticket/5559 <p> Just catch a bug: interval_set works not correct with custom compare function. Here is the test case, it fails with boost 1.46.1 and truck version (23 May 2011, svn revision 72124). It works ok with default std::less comparator. </p> <p> Of course, it is weird to use std::greater with int as it is in this listing. Here is a simplified test case, I got the bug using a custom datatype (int64_t inside) with a custom comparator. I did not investigated it yet. It looks like icl::succ and icl::pred should be customized together with comparator. </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;assert.h&gt; #include &lt;boost/cstdint.hpp&gt; #include &lt;boost/icl/interval_set.hpp&gt; int main() { typedef boost::icl::interval_set&lt;boost::uint32_t, ICL_COMPARE_INSTANCE(std::greater, boost::uint32_t)&gt; Set; Set q1( Set::interval_type::closed(UINT32_MAX, 0) ); Set q2( Set::interval_type::closed(1000, 100) ); Set q3( Set::interval_type::closed(1, 1) ); Set q4( Set::interval_type::closed(1, 0) ); Set q5( Set::interval_type::closed(0, 0) ); std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q2 &lt;&lt; " = " &lt;&lt; (q1+q2) &lt;&lt; std::endl; // ok std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q3 &lt;&lt; " = " &lt;&lt; (q1+q3) &lt;&lt; std::endl; // incorrect result std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q4 &lt;&lt; " = " &lt;&lt; (q1+q4) &lt;&lt; std::endl; // incorrect result std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q5 &lt;&lt; " = " &lt;&lt; (q1+q5) &lt;&lt; std::endl; // assertion inside icl assert(q1 == q1+q2); assert(q1 == q1+q3); assert(q1 == q1+q4); assert(q1 == q1+q5); } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5559 Trac 1.4.3 denis@… Tue, 24 May 2011 13:27:58 GMT <link>https://svn.boost.org/trac10/ticket/5559#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5559#comment:1</guid> <description> <p> This can be worked around this way </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;assert.h&gt; #include &lt;boost/cstdint.hpp&gt; #include &lt;boost/icl/interval_set.hpp&gt; class rint { boost::uint32_t i_; public: rint(int i=0) : i_(i) {} operator boost::uint32_t() const { return i_; } const rint&amp; operator++() { ++i_; return *this; } const rint&amp; operator--() { --i_; return *this; } bool operator &lt;(rint r) const { return i_ &lt; r.i_; } bool operator &gt;(rint r) const { return i_ &gt; r.i_; } }; namespace boost{ namespace icl { template &lt;&gt; inline rint succ(rint x) { return --x; } template &lt;&gt; inline rint pred(rint x) { return ++x; } }} int main() { typedef boost::icl::interval_set&lt;rint, ICL_COMPARE_INSTANCE(std::greater, rint)&gt; Set; Set q1( Set::interval_type::closed(UINT32_MAX, 0) ); Set q2( Set::interval_type::closed(1000, 100) ); Set q3( Set::interval_type::closed(1, 1) ); Set q4( Set::interval_type::closed(1, 0) ); Set q5( Set::interval_type::closed(0, 0) ); std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q2 &lt;&lt; " = " &lt;&lt; (q1+q2) &lt;&lt; std::endl; // ok std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q3 &lt;&lt; " = " &lt;&lt; (q1+q3) &lt;&lt; std::endl; // ok std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q4 &lt;&lt; " = " &lt;&lt; (q1+q4) &lt;&lt; std::endl; // ok std::cout &lt;&lt; q1 &lt;&lt; " + " &lt;&lt; q5 &lt;&lt; " = " &lt;&lt; (q1+q5) &lt;&lt; std::endl; // ok assert(q1 == q1+q2); assert(q1 == q1+q3); assert(q1 == q1+q4); assert(q1 == q1+q5); } </pre><p> It is a bit strange, that Compare is settable per-container while succ() and pred() is settable per-type. discrete_interval needs all 3 function be performable on its domain and all of them to be consistent. Thus, per-type defined succ() and pred() give no chance for Compare to be chosen freely per-container. If succ() does increment then Compare has to be std::less, if succ() does decrement then Compare has to be std::greater, etc </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joachim Faulhaber</dc:creator> <pubDate>Wed, 25 May 2011 10:59:47 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5559#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5559#comment:2</guid> <description> <p> Hi Denis, </p> <p> thank you for your input. Your code example does not compile with the include-files given. UINT32_MAX is not defined. When using (std::numeric_limits&lt;uint32_t&gt;::max)() instead, I found that the claimed bugs for q3 and q4 do not occur. </p> <p> Which leaves us with the assertion violation from case q5. I have fixed the code for that and created a test. </p> <div class="wiki-code"><div class="code"><pre><span class="n">BOOST_AUTO_TEST_CASE</span><span class="p">(</span><span class="n">ticket_5559_Denis</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//Submitted by Denis</span> <span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">icl</span><span class="o">::</span><span class="n">interval_set</span><span class="o">&lt;</span><span class="n">boost</span><span class="o">::</span><span class="kt">uint32_t</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">greater</span><span class="o">&gt;</span> <span class="n">Set</span><span class="p">;</span> <span class="k">const</span> <span class="kt">uint32_t</span> <span class="n">ui32_max</span> <span class="o">=</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="kt">uint32_t</span><span class="o">&gt;::</span><span class="n">max</span><span class="p">)();</span> <span class="n">Set</span> <span class="nf">q1</span><span class="p">(</span> <span class="n">Set</span><span class="o">::</span><span class="n">interval_type</span><span class="o">::</span><span class="n">closed</span><span class="p">(</span><span class="n">ui32_max</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="p">);</span> <span class="n">Set</span> <span class="nf">q5</span><span class="p">(</span> <span class="n">Set</span><span class="o">::</span><span class="n">interval_type</span><span class="o">::</span><span class="n">closed</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="p">);</span> <span class="n">BOOST_CHECK_EQUAL</span><span class="p">(</span><span class="n">q1</span><span class="p">,</span> <span class="n">q1</span><span class="o">+</span><span class="n">q5</span><span class="p">);</span> <span class="p">}</span> </pre></div></div><p> Cheers, Joachim </p> </description> <category>Ticket</category> </item> <item> <author>denis@…</author> <pubDate>Wed, 25 May 2011 11:40:12 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5559#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5559#comment:3</guid> <description> <p> q3 and q4 bugs seem to <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5482" title="#5482: Bugs: iterative_size() not the same for interval_maps using std::less and ... (closed: fixed)">#5482</a> </p> </description> <category>Ticket</category> </item> <item> <author>denis@…</author> <pubDate>Wed, 25 May 2011 11:40:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5559#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5559#comment:4</guid> <description> <p> q3 and q4 bugs seem to be <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5482" title="#5482: Bugs: iterative_size() not the same for interval_maps using std::less and ... (closed: fixed)">#5482</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joachim Faulhaber</dc:creator> <pubDate>Wed, 25 May 2011 11:46:44 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/5559#comment:5 https://svn.boost.org/trac10/ticket/5559#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket Joachim Faulhaber Sun, 05 Jun 2011 13:45:13 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/5559#comment:6 https://svn.boost.org/trac10/ticket/5559#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket