mirror of
				https://github.com/boostorg/utility.git
				synced 2025-11-04 02:11:45 +01:00 
			
		
		
		
	
		
			
	
	
		
			739 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			739 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| 
								 | 
							
								<html>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<head>
							 | 
						|||
| 
								 | 
							
								<meta http-equiv="Content-Type"
							 | 
						|||
| 
								 | 
							
								content="text/html; charset=iso-8859-1">
							 | 
						|||
| 
								 | 
							
								<meta name="Template"
							 | 
						|||
| 
								 | 
							
								content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
							 | 
						|||
| 
								 | 
							
								<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
							 | 
						|||
| 
								 | 
							
								<title>Call Traits</title>
							 | 
						|||
| 
								 | 
							
								</head>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
							 | 
						|||
| 
								 | 
							
								vlink="#800080">
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h1><img src="../../c++boost.gif" width="276" height="86">Header
							 | 
						|||
| 
								 | 
							
								<<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>></h1>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>All of the contents of <boost/call_traits.hpp> are
							 | 
						|||
| 
								 | 
							
								defined inside namespace boost.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The template class call_traits<T> encapsulates the
							 | 
						|||
| 
								 | 
							
								"best" method to pass a parameter of some type T to or
							 | 
						|||
| 
								 | 
							
								from a function, and consists of a collection of typedefs defined
							 | 
						|||
| 
								 | 
							
								as in the table below. The purpose of call_traits is to ensure
							 | 
						|||
| 
								 | 
							
								that problems like "<a href="#refs">references to references</a>"
							 | 
						|||
| 
								 | 
							
								never occur, and that parameters are passed in the most efficient
							 | 
						|||
| 
								 | 
							
								manner possible (see <a href="#examples">examples</a>). In each
							 | 
						|||
| 
								 | 
							
								case if your existing practice is to use the type defined on the
							 | 
						|||
| 
								 | 
							
								left, then replace it with the call_traits defined type on the
							 | 
						|||
| 
								 | 
							
								right. Note that for compilers that do not support partial
							 | 
						|||
| 
								 | 
							
								specialization, no benefit will occur from using call_traits: the
							 | 
						|||
| 
								 | 
							
								call_traits defined types will always be the same as the existing
							 | 
						|||
| 
								 | 
							
								practice in this case.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<table border="0" cellpadding="7" cellspacing="1" width="797">
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#008080"><p
							 | 
						|||
| 
								 | 
							
								        align="center">Existing practice</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="35%" bgcolor="#008080"><p
							 | 
						|||
| 
								 | 
							
								        align="center">call_traits equivalent</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="32%" bgcolor="#008080"><p
							 | 
						|||
| 
								 | 
							
								        align="center">Description</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="16%" bgcolor="#008080"><p
							 | 
						|||
| 
								 | 
							
								        align="center">Notes</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">T<br>
							 | 
						|||
| 
								 | 
							
								        (return by value)</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::value_type</code></p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="32%">Defines a type that
							 | 
						|||
| 
								 | 
							
								        represents the "value" of type T. Use this for
							 | 
						|||
| 
								 | 
							
								        functions that return by value, or possibly for stored
							 | 
						|||
| 
								 | 
							
								        values of type T.</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="16%"><p align="center">2</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">T&<br>
							 | 
						|||
| 
								 | 
							
								        (return value)</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::reference</code></p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="32%">Defines a type that
							 | 
						|||
| 
								 | 
							
								        represents a reference to type T. Use for functions that
							 | 
						|||
| 
								 | 
							
								        would normally return a T&.</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="16%"><p align="center">1</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const T&<br>
							 | 
						|||
| 
								 | 
							
								        (return value)</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::const_reference</code></p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="32%">Defines a type that
							 | 
						|||
| 
								 | 
							
								        represents a constant reference to type T. Use for
							 | 
						|||
| 
								 | 
							
								        functions that would normally return a const T&.</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="16%"><p align="center">1</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const T&<br>
							 | 
						|||
| 
								 | 
							
								        (function parameter)</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="32%">Defines a type that
							 | 
						|||
| 
								 | 
							
								        represents the "best" way to pass a parameter
							 | 
						|||
| 
								 | 
							
								        of type T to a function.</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="16%"><p align="center">1,3</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								</table>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Notes:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<ol>
							 | 
						|||
| 
								 | 
							
								    <li>If T is already reference type, then call_traits is
							 | 
						|||
| 
								 | 
							
								        defined such that <a href="#refs">references to
							 | 
						|||
| 
								 | 
							
								        references</a> do not occur (requires partial
							 | 
						|||
| 
								 | 
							
								        specialization).</li>
							 | 
						|||
| 
								 | 
							
								    <li>If T is an array type, then call_traits defines <code>value_type</code>
							 | 
						|||
| 
								 | 
							
								        as a "constant pointer to type" rather than an
							 | 
						|||
| 
								 | 
							
								        "array of type" (requires partial
							 | 
						|||
| 
								 | 
							
								        specialization). Note that if you are using value_type as
							 | 
						|||
| 
								 | 
							
								        a stored value then this will result in storing a "constant
							 | 
						|||
| 
								 | 
							
								        pointer to an array" rather than the array itself.
							 | 
						|||
| 
								 | 
							
								        This may or may not be a good thing depending upon what
							 | 
						|||
| 
								 | 
							
								        you actually need (in other words take care!).</li>
							 | 
						|||
| 
								 | 
							
								    <li>If T is a small built in type or a pointer, then <code>param_type</code>
							 | 
						|||
| 
								 | 
							
								        is defined as <code>T const</code>, instead of <code>T
							 | 
						|||
| 
								 | 
							
								        const&</code>. This can improve the ability of the
							 | 
						|||
| 
								 | 
							
								        compiler to optimize loops in the body of the function if
							 | 
						|||
| 
								 | 
							
								        they depend upon the passed parameter, the semantics of
							 | 
						|||
| 
								 | 
							
								        the passed parameter is otherwise unchanged (requires
							 | 
						|||
| 
								 | 
							
								        partial specialization).</li>
							 | 
						|||
| 
								 | 
							
								</ol>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p> </p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3>Copy constructibility</h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The following table defines which call_traits types can always
							 | 
						|||
| 
								 | 
							
								be copy-constructed from which other types, those entries marked
							 | 
						|||
| 
								 | 
							
								with a '?' are true only if and only if T is copy constructible:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<table border="0" cellpadding="7" cellspacing="1" width="766">
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"> </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" colspan="5" width="85%"
							 | 
						|||
| 
								 | 
							
								        bgcolor="#008080"><p align="center">To:</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#008080">From:</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">T</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">value_type</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">reference</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">const_reference</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">param_type</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">N</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">N</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">N</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">N</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">?</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">N</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">N</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								</table>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p> </p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>If T is an assignable type the following assignments are
							 | 
						|||
| 
								 | 
							
								possible:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<table border="0" cellpadding="7" cellspacing="1" width="766">
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"> </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" colspan="5" width="85%"
							 | 
						|||
| 
								 | 
							
								        bgcolor="#008080"><p align="center">To:</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#008080">From:</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">T</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">value_type</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">reference</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">const_reference</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">param_type</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">Y</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">-</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								</table>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p> </p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="examples"></a>Examples</h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The following table shows the effect that call_traits has on
							 | 
						|||
| 
								 | 
							
								various types, the table assumes that the compiler supports
							 | 
						|||
| 
								 | 
							
								partial specialization: if it doesn't then all types behave in
							 | 
						|||
| 
								 | 
							
								the same way as the entry for "myclass", and call_traits
							 | 
						|||
| 
								 | 
							
								can not be used with reference or array types.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<table border="0" cellpadding="7" cellspacing="1" width="766">
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"> </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" colspan="5" width="85%"
							 | 
						|||
| 
								 | 
							
								        bgcolor="#008080"><p align="center">Call_traits type:</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#008080"><p
							 | 
						|||
| 
								 | 
							
								        align="center">Original type T</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">value_type</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">reference</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">const_reference</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">param_type</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">Applies to:</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">myclass</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">myclass</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">myclass&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const
							 | 
						|||
| 
								 | 
							
								        myclass&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">myclass
							 | 
						|||
| 
								 | 
							
								        const&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All user
							 | 
						|||
| 
								 | 
							
								        defined types.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">int</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int const</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All small
							 | 
						|||
| 
								 | 
							
								        built-in types.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">int*</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int*</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int*&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int*const&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int* const</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All
							 | 
						|||
| 
								 | 
							
								        pointer types.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All
							 | 
						|||
| 
								 | 
							
								        reference types.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int&</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All
							 | 
						|||
| 
								 | 
							
								        constant-references.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">int[3]</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int*</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">int(&)[3]</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int(&)[3]</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int*
							 | 
						|||
| 
								 | 
							
								        const</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All array
							 | 
						|||
| 
								 | 
							
								        types.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								    <tr>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
							 | 
						|||
| 
								 | 
							
								        align="center">const int[3]</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int*</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int(&)[3]</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int(&)[3]</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">const int*
							 | 
						|||
| 
								 | 
							
								        const</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								        <td valign="top" width="17%"><p align="center">All
							 | 
						|||
| 
								 | 
							
								        constant-array types.</p>
							 | 
						|||
| 
								 | 
							
								        </td>
							 | 
						|||
| 
								 | 
							
								    </tr>
							 | 
						|||
| 
								 | 
							
								</table>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p> </p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h4>Example 1:</h4>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The following class is a trivial class that stores some type T
							 | 
						|||
| 
								 | 
							
								by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
							 | 
						|||
| 
								 | 
							
								file), the aim is to illustrate how each of the available call_traits
							 | 
						|||
| 
								 | 
							
								typedefs may be used:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>template <class T>
							 | 
						|||
| 
								 | 
							
								struct contained
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   // define our typedefs first, arrays are stored by value
							 | 
						|||
| 
								 | 
							
								   // so value_type is not the same as result_type:
							 | 
						|||
| 
								 | 
							
								   typedef typename boost::call_traits<T>::param_type       param_type;
							 | 
						|||
| 
								 | 
							
								   typedef typename boost::call_traits<T>::reference        reference;
							 | 
						|||
| 
								 | 
							
								   typedef typename boost::call_traits<T>::const_reference  const_reference;
							 | 
						|||
| 
								 | 
							
								   typedef T                                                value_type;
							 | 
						|||
| 
								 | 
							
								   typedef typename boost::call_traits<T>::value_type       result_type;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								   // stored value:
							 | 
						|||
| 
								 | 
							
								   value_type v_;
							 | 
						|||
| 
								 | 
							
								   
							 | 
						|||
| 
								 | 
							
								   // constructors:
							 | 
						|||
| 
								 | 
							
								   contained() {}
							 | 
						|||
| 
								 | 
							
								   contained(param_type p) : v_(p){}
							 | 
						|||
| 
								 | 
							
								   // return byval:
							 | 
						|||
| 
								 | 
							
								   result_type value() { return v_; }
							 | 
						|||
| 
								 | 
							
								   // return by_ref:
							 | 
						|||
| 
								 | 
							
								   reference get() { return v_; }
							 | 
						|||
| 
								 | 
							
								   const_reference const_get()const { return v_; }
							 | 
						|||
| 
								 | 
							
								   // pass value:
							 | 
						|||
| 
								 | 
							
								   void call(param_type p){}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								};</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h4><a name="refs"></a>Example 2 (the reference to reference
							 | 
						|||
| 
								 | 
							
								problem):</h4>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Consider the definition of std::binder1st:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>template <class Operation> 
							 | 
						|||
| 
								 | 
							
								class binder1st : 
							 | 
						|||
| 
								 | 
							
								   public unary_function<Operation::second_argument_type, Operation::result_type> 
							 | 
						|||
| 
								 | 
							
								{ 
							 | 
						|||
| 
								 | 
							
								protected: 
							 | 
						|||
| 
								 | 
							
								   Operation op; 
							 | 
						|||
| 
								 | 
							
								   Operation::first_argument_type value; 
							 | 
						|||
| 
								 | 
							
								public: 
							 | 
						|||
| 
								 | 
							
								   binder1st(const Operation& x, const Operation::first_argument_type& y); 
							 | 
						|||
| 
								 | 
							
								   Operation::result_type operator()(const Operation::second_argument_type& x) const; 
							 | 
						|||
| 
								 | 
							
								}; </pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Now consider what happens in the relatively common case that
							 | 
						|||
| 
								 | 
							
								the functor takes its second argument as a reference, that
							 | 
						|||
| 
								 | 
							
								implies that <code>Operation::second_argument_type</code> is a
							 | 
						|||
| 
								 | 
							
								reference type, <code>operator()</code> will now end up taking a
							 | 
						|||
| 
								 | 
							
								reference to a reference as an argument, and that is not
							 | 
						|||
| 
								 | 
							
								currently legal. The solution here is to modify <code>operator()</code>
							 | 
						|||
| 
								 | 
							
								to use call_traits:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>Operation::result_type operator()(call_traits<Operation::second_argument_type>::param_type x) const;</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Now in the case that <code>Operation::second_argument_type</code>
							 | 
						|||
| 
								 | 
							
								is a reference type, the argument is passed as a reference, and
							 | 
						|||
| 
								 | 
							
								the no "reference to reference" occurs.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h4><a name="ex3"></a>Example 3 (the make_pair problem):</h4>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>If we pass the name of an array as one (or both) arguments to <code>std::make_pair</code>,
							 | 
						|||
| 
								 | 
							
								then template argument deduction deduces the passed parameter as
							 | 
						|||
| 
								 | 
							
								"const reference to array of T", this also applies to
							 | 
						|||
| 
								 | 
							
								string literals (which are really array literals). Consequently
							 | 
						|||
| 
								 | 
							
								instead of returning a pair of pointers, it tries to return a
							 | 
						|||
| 
								 | 
							
								pair of arrays, and since an array type is not copy-constructible
							 | 
						|||
| 
								 | 
							
								the code fails to compile. One solution is to explicitly cast the
							 | 
						|||
| 
								 | 
							
								arguments to make_pair to pointers, but call_traits provides a
							 | 
						|||
| 
								 | 
							
								better (i.e. automatic) solution (and one that works safely even
							 | 
						|||
| 
								 | 
							
								in generic code where the cast might do the wrong thing):</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>template <class T1, class T2>
							 | 
						|||
| 
								 | 
							
								std::pair<
							 | 
						|||
| 
								 | 
							
								   typename boost::call_traits<T1>::value_type, 
							 | 
						|||
| 
								 | 
							
								   typename boost::call_traits<T2>::value_type> 
							 | 
						|||
| 
								 | 
							
								      make_pair(const T1& t1, const T2& t2)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   return std::pair<
							 | 
						|||
| 
								 | 
							
								      typename boost::call_traits<T1>::value_type, 
							 | 
						|||
| 
								 | 
							
								      typename boost::call_traits<T2>::value_type>(t1, t2);
							 | 
						|||
| 
								 | 
							
								}</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Here, the deduced argument types will be automatically
							 | 
						|||
| 
								 | 
							
								degraded to pointers if the deduced types are arrays, similar
							 | 
						|||
| 
								 | 
							
								situations occur in the standard binders and adapters: in
							 | 
						|||
| 
								 | 
							
								principle in any function that "wraps" a temporary
							 | 
						|||
| 
								 | 
							
								whose type is deduced.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The call_traits template will "optimize" the passing
							 | 
						|||
| 
								 | 
							
								of a small built-in type as a function parameter, this mainly has
							 | 
						|||
| 
								 | 
							
								an effect when the parameter is used within a loop body. In the
							 | 
						|||
| 
								 | 
							
								following example (see <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>),
							 | 
						|||
| 
								 | 
							
								a version of std::fill is optimized in two ways: if the type
							 | 
						|||
| 
								 | 
							
								passed is a single byte built-in type then std::memset is used to
							 | 
						|||
| 
								 | 
							
								effect the fill, otherwise a conventional C++ implemention is
							 | 
						|||
| 
								 | 
							
								used, but with the passed parameter "optimized" using
							 | 
						|||
| 
								 | 
							
								call_traits:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>namespace detail{
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								template <bool opt>
							 | 
						|||
| 
								 | 
							
								struct filler
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   template <typename I, typename T>
							 | 
						|||
| 
								 | 
							
								   static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val);
							 | 
						|||
| 
								 | 
							
								   {
							 | 
						|||
| 
								 | 
							
								      while(first != last)
							 | 
						|||
| 
								 | 
							
								      {
							 | 
						|||
| 
								 | 
							
								         *first = val;
							 | 
						|||
| 
								 | 
							
								         ++first;
							 | 
						|||
| 
								 | 
							
								      }
							 | 
						|||
| 
								 | 
							
								   }
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								template <>
							 | 
						|||
| 
								 | 
							
								struct filler<true>
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   template <typename I, typename T>
							 | 
						|||
| 
								 | 
							
								   static void do_fill(I first, I last, T val)
							 | 
						|||
| 
								 | 
							
								   {
							 | 
						|||
| 
								 | 
							
								      memset(first, val, last-first);
							 | 
						|||
| 
								 | 
							
								   }
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								template <class I, class T>
							 | 
						|||
| 
								 | 
							
								inline void fill(I first, I last, const T& val)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   enum{ can_opt = boost::is_pointer<I>::value
							 | 
						|||
| 
								 | 
							
								                   && boost::is_arithmetic<T>::value
							 | 
						|||
| 
								 | 
							
								                   && (sizeof(T) == 1) };
							 | 
						|||
| 
								 | 
							
								   typedef detail::filler<can_opt> filler_t;
							 | 
						|||
| 
								 | 
							
								   filler_t::template do_fill<I,T>(first, last, val);
							 | 
						|||
| 
								 | 
							
								}</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Footnote: the reason that this is "optimal" for
							 | 
						|||
| 
								 | 
							
								small built-in types is that with the value passed as "T
							 | 
						|||
| 
								 | 
							
								const" instead of "const T&" the compiler is
							 | 
						|||
| 
								 | 
							
								able to tell both that the value is constant and that it is free
							 | 
						|||
| 
								 | 
							
								of aliases. With this information the compiler is able to cache
							 | 
						|||
| 
								 | 
							
								the passed value in a register, unroll the loop, or use
							 | 
						|||
| 
								 | 
							
								explicitly parallel instructions: if any of these are supported.
							 | 
						|||
| 
								 | 
							
								Exactly how much mileage you will get from this depends upon your
							 | 
						|||
| 
								 | 
							
								compiler - we could really use some accurate benchmarking
							 | 
						|||
| 
								 | 
							
								software as part of boost for cases like this.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3>Rationale</h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The following notes are intended to briefly describe the
							 | 
						|||
| 
								 | 
							
								rational behind choices made in call_traits.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>All user-defined types follow "existing practice"
							 | 
						|||
| 
								 | 
							
								and need no comment.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Small built-in types (what the standard calls fundamental
							 | 
						|||
| 
								 | 
							
								types [3.9.1]) differ from existing practice only in the <i>param_type</i>
							 | 
						|||
| 
								 | 
							
								typedef. In this case passing "T const" is compatible
							 | 
						|||
| 
								 | 
							
								with existing practice, but may improve performance in some cases
							 | 
						|||
| 
								 | 
							
								(see <a href="#ex4">Example 4</a>), in any case this should never
							 | 
						|||
| 
								 | 
							
								be any worse than existing practice.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Pointers follow the same rational as small built-in types.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>For reference types the rational follows <a href="#refs">Example
							 | 
						|||
| 
								 | 
							
								2</a> - references to references are not allowed, so the call_traits
							 | 
						|||
| 
								 | 
							
								members must be defined such that these problems do not occur.
							 | 
						|||
| 
								 | 
							
								There is a proposal to modify the language such that "a
							 | 
						|||
| 
								 | 
							
								reference to a reference is a reference" (issue #106,
							 | 
						|||
| 
								 | 
							
								submitted by Bjarne Stroustrup), call_traits<T>::value_type
							 | 
						|||
| 
								 | 
							
								and call_traits<T>::param_type both provide the same effect
							 | 
						|||
| 
								 | 
							
								as that proposal, without the need for a language change (in
							 | 
						|||
| 
								 | 
							
								other words it's a workaround).</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>For array types, a function that takes an array as an argument
							 | 
						|||
| 
								 | 
							
								will degrade the array type to a pointer type: this means that
							 | 
						|||
| 
								 | 
							
								the type of the actual parameter is different from its declared
							 | 
						|||
| 
								 | 
							
								type, something that can cause endless problems in template code
							 | 
						|||
| 
								 | 
							
								that relies on the declared type of a parameter. For example:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>template <class T>
							 | 
						|||
| 
								 | 
							
								struct A
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   void foo(T t);
							 | 
						|||
| 
								 | 
							
								};</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p><font face="Times New Roman">In this case if we instantiate A<int[2]>
							 | 
						|||
| 
								 | 
							
								then the declared type of the parameter passed to member function
							 | 
						|||
| 
								 | 
							
								foo is int[2], but it's actual type is const int*, if we try to
							 | 
						|||
| 
								 | 
							
								use the type T within the function body, then there is a strong
							 | 
						|||
| 
								 | 
							
								likelyhood that our code will not compile:</font></p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>template <class T>
							 | 
						|||
| 
								 | 
							
								void A<T>::foo(T t)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   T dup(t); // doesn't compile for case that T is an array.
							 | 
						|||
| 
								 | 
							
								}</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>By using call_traits the degradation from array to pointer is
							 | 
						|||
| 
								 | 
							
								explicit, and the type of the parameter is the same as it's
							 | 
						|||
| 
								 | 
							
								declared type:</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<pre>template <class T>
							 | 
						|||
| 
								 | 
							
								struct A
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   void foo(call_traits<T>::value_type t);
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								template <class T>
							 | 
						|||
| 
								 | 
							
								void A<T>::foo(call_traits<T>::value_type t)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								   call_traits<T>::value_type dup(t); // OK even if T is an array type.
							 | 
						|||
| 
								 | 
							
								}</pre>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>For value_type (return by value), again only a pointer may be
							 | 
						|||
| 
								 | 
							
								returned, not a copy of the whole array, and again call_traits
							 | 
						|||
| 
								 | 
							
								makes the degradation explicit. The value_type member is useful
							 | 
						|||
| 
								 | 
							
								whenever an array must be explicitly degraded to a pointer - <a
							 | 
						|||
| 
								 | 
							
								href="#ex3">Example 3</a> provides the test case (Footnote: the
							 | 
						|||
| 
								 | 
							
								array specialisation for call_traits is the least well understood
							 | 
						|||
| 
								 | 
							
								of all the call_traits specialisations, if the given semantics
							 | 
						|||
| 
								 | 
							
								cause specific problems for you, or don't solve a particular
							 | 
						|||
| 
								 | 
							
								array-related problem, then I would be interested to hear about
							 | 
						|||
| 
								 | 
							
								it. Most people though will probably never need to use this
							 | 
						|||
| 
								 | 
							
								specialisation).</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<hr>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Revised 18 June 2000</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
							 | 
						|||
| 
								 | 
							
								sell and distribute this document is granted provided this
							 | 
						|||
| 
								 | 
							
								copyright notice appears in all copies. This document is provided
							 | 
						|||
| 
								 | 
							
								"as is" without express or implied warranty, and with
							 | 
						|||
| 
								 | 
							
								no claim as to its suitability for any purpose.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
							 | 
						|||
| 
								 | 
							
								Hinnant and John Maddock.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
							 | 
						|||
| 
								 | 
							
								Maddock</a>, the latest version of this file can be found at <a
							 | 
						|||
| 
								 | 
							
								href="http://www.boost.org/">www.boost.org</a>, and the boost
							 | 
						|||
| 
								 | 
							
								discussion list at <a href="http://www.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p> </p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p> </p>
							 | 
						|||
| 
								 | 
							
								</body>
							 | 
						|||
| 
								 | 
							
								</html>
							 |