Boost C++ Libraries: Ticket #2862: slist::swap is broken when cache_last< true > is used https://svn.boost.org/trac10/ticket/2862 <p> Swapping two slists with the cache_last option yields an invalid slist. The following code snippet demonstrates the problem: </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;boost/checked_delete.hpp&gt; #include &lt;boost/intrusive/options.hpp&gt; #include &lt;boost/intrusive/slist.hpp&gt; #include &lt;boost/intrusive/slist_hook.hpp&gt; namespace bi = boost::intrusive; typedef bi::slist_base_hook&lt; bi::link_mode&lt; bi::safe_link &gt; &gt; BaseHook_t; struct MyData : public BaseHook_t { int m_Data; explicit MyData(int d) : m_Data(d) {} }; int main(int, char*[]) { typedef bi::slist&lt; MyData, bi::base_hook&lt; BaseHook_t &gt;, bi::constant_time_size&lt; true &gt;, bi::cache_last&lt; true &gt; &gt; List_t; List_t l1; MyData* p = 0; p = new MyData(1); l1.push_back(*p); p = new MyData(2); l1.push_back(*p); p = new MyData(3); l1.push_back(*p); p = new MyData(4); l1.push_back(*p); std::cout &lt;&lt; "l1.front() = " &lt;&lt; &amp;l1.front() &lt;&lt; std::endl; List_t l2; l2.swap(l1); std::cout &lt;&lt; "l2.front() = " &lt;&lt; &amp;l2.front() &lt;&lt; std::endl; // should be the same as l1.front() above l2.clear_and_dispose(boost::checked_deleter&lt; MyData &gt;()); // this line crashes return 0; } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2862 Trac 1.4.3 Andrey Semashev Tue, 17 Mar 2009 07:43:59 GMT <link>https://svn.boost.org/trac10/ticket/2862#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2862#comment:1</guid> <description> <p> An addition: looks like the problem occurs only when one of the lists is empty. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Tue, 17 Mar 2009 08:06:32 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2862#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2862#comment:2</guid> <description> <p> The following version of the priv_swap_cache_last method fixes the problem for me, although I'm not sure it's acceptable: </p> <pre class="wiki"> void priv_swap_cache_last(slist_impl &amp;other) { int choice = static_cast&lt; int &gt;(this-&gt;empty()) * 2 + static_cast&lt; int &gt;(other.empty()); switch (choice) { case 0: // both lists are not empty { node_ptr other_last(other.get_last_node()); node_ptr this_last(this-&gt;get_last_node()); node_ptr other_bfirst(other.get_root_node()); node_ptr this_bfirst(this-&gt;get_root_node()); node_algorithms::transfer_after(this_bfirst, other_bfirst, other_last); node_algorithms::transfer_after(other_bfirst, other_last != other_bfirst? other_last : this_bfirst, this_last); node_ptr tmp(this-&gt;get_last_node()); this-&gt;set_last_node(other.get_last_node()); other.set_last_node(tmp); } break; case 1: // other.empty() == true other.splice_after(other.before_begin(), *this); break; case 2: // this-&gt;empty() == true this-&gt;splice_after(this-&gt;before_begin(), other); break; default:; // both lists are empty } } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Tue, 17 Mar 2009 08:09:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2862#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2862#comment:3</guid> <description> <p> Oh, just noticed, there's no need for the "other_last != other_bfirst" comparison as it always yields true in the proposed priv_swap_cache_last version. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Tue, 17 Mar 2009 08:15:03 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2862#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2862#comment:4</guid> <description> <p> On the second thought, ignore it. The splice_after breaks the constatnt_time_size behavior. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 25 Mar 2009 18:13:42 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/2862#comment:5 https://svn.boost.org/trac10/ticket/2862#comment:5 <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> Fixed in revision 51971. </p> Ticket