Boost C++ Libraries: Ticket #6149: as_literal used on string container making unnecessary expensive copy https://svn.boost.org/trac10/ticket/6149 <p> The following problem is not only an optimization problem since it can slow down applications. It is also not limited to boost 1.48.0. It did exist in previous versions already, but is still present in 1.48.0. </p> <p> boost/range/as_literal.hpp uses range_detail::is_char_ptr() to distinguish if a passed T is a character pointer or convertible to character pointer. </p> <pre class="wiki">template&lt; class T &gt; inline long is_char_ptr( T /* r */ ) </pre><p> is problematic when T is a string container. An expensive copy of the passed string object is created and immediately deleted again. You might think it should be subject to compiler optimization in release builds. But I encountered it at least in a project release build with optimization enabled on Visual Studio 2005 Professional, seen in the disassembly. </p> <p> A solution should be easy by preventing calling is_char_ptr() directly and instead doing an indirection over a template class: </p> <pre class="wiki">namespace range_detail { template&lt; class T &gt; struct check_char_ptr : public boost::integral_constant&lt; bool, sizeof(boost::range_detail::is_char_ptr( * (T*) 0 )) == sizeof(bool) &gt; { typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c&lt; value, bool, long &gt;::type choice_type; }; } template&lt; class Range &gt; inline boost::iterator_range&lt; BOOST_DEDUCED_TYPENAME boost::range_iterator&lt; Range &gt;::type &gt; as_literal( Range&amp; r ) { return boost::range_detail::make_range( r, range_detail::check_char_ptr&lt; Range &gt;::choice_type() ); } template&lt; class Range &gt; inline boost::iterator_range&lt; BOOST_DEDUCED_TYPENAME boost::range_iterator&lt; const Range &gt;::type &gt; as_literal( const Range&amp; r ) { return boost::range_detail::make_range( r, range_detail::check_char_ptr&lt; Range &gt;::choice_type() ); } template&lt; class Char, std::size_t sz &gt; inline boost::iterator_range&lt; Char* &gt; as_literal( Char (&amp;r) [sz] ) { return boost::range_detail::make_range( r, range_detail::check_char_ptr&lt; Char* &gt;::choice_type() ); } template&lt; class Char, std::size_t sz &gt; inline boost::iterator_range&lt; const Char* &gt; as_literal( const Char (&amp;r) [sz] ) { return boost::range_detail::make_range( r, range_detail::check_char_ptr&lt; Char* &gt;::choice_type() ); } </pre><p> That's the solution I am using right now. Neither debug nor release build (only checked in VS2005) includes a call to range_detail::is_char_ptr(), seen in the disassembly. It still is using range_detail::is_char_ptr() to reflect the previous behaviour also in terms of convertability of T to a character pointer type. </p> <p> If the use of mpl is not desirable, it should be easy to write it manually with template specialization. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6149 Trac 1.4.3 Michael Burr <michael.burr@…> Tue, 20 Dec 2011 09:28:21 GMT <link>https://svn.boost.org/trac10/ticket/6149#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6149#comment:1</guid> <description> <p> See duplicate bug <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/6305" title="#6305: Bugs: range_detail::make_range() copies containers needlessly (closed: duplicate)">#6305</a> for a patch that has what I think is a simpler solution. Just have the <code>range_detail::make_range()</code> 'catch all' template function take a <code>T const&amp;</code> parameter instead of a simple value parameter to avoid the copy. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Neil Groves</dc:creator> <pubDate>Sun, 15 Apr 2012 12:16:43 GMT</pubDate> <title>status, milestone changed; resolution set https://svn.boost.org/trac10/ticket/6149#comment:2 https://svn.boost.org/trac10/ticket/6149#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> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.50.0</span> </li> </ul> <p> Resolved on trunk. </p> Ticket