call_traits and type_traits updates for VC6

[SVN r7882]
This commit is contained in:
John Maddock 2000-10-01 11:48:27 +00:00
parent c5915c23e7
commit 7ae6e5bac9
3 changed files with 118 additions and 19 deletions

View File

@ -27,10 +27,16 @@ never occur, and that parameters are passed in the most efficient
manner possible (see <a href="#examples">examples</a>). In each manner possible (see <a href="#examples">examples</a>). In each
case if your existing practice is to use the type defined on the 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 left, then replace it with the call_traits defined type on the
right. Note that for compilers that do not support partial right. </p>
specialization, no benefit will occur from using call_traits: the
call_traits defined types will always be the same as the existing <p>Note that for compilers that do not support either partial
practice in this case.</p> specialization or member templates, 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. In addition if
only member templates and not partial template specialisation is
support by the compiler (for example Visual C++ 6) then call_traits
can not be used with array types (although it can be used to
solve the reference to reference problem).</p>
<table border="0" cellpadding="7" cellspacing="1" width="797"> <table border="0" cellpadding="7" cellspacing="1" width="797">
<tr> <tr>
@ -569,7 +575,9 @@ std::pair&lt;
degraded to pointers if the deduced types are arrays, similar degraded to pointers if the deduced types are arrays, similar
situations occur in the standard binders and adapters: in situations occur in the standard binders and adapters: in
principle in any function that &quot;wraps&quot; a temporary principle in any function that &quot;wraps&quot; a temporary
whose type is deduced.</p> whose type is deduced. Note that the function arguments to make_pair
are not expressed in terms of call_traits: doing so would prevent
template argument deduction from functioning.</p>
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4> <h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
@ -632,6 +640,14 @@ Exactly how much mileage you will get from this depends upon your
compiler - we could really use some accurate benchmarking compiler - we could really use some accurate benchmarking
software as part of boost for cases like this.</p> software as part of boost for cases like this.</p>
<p>Note that the function arguments to fill are not expressed in
terms of call_traits: doing so would prevent template argument
deduction from functioning. Instead fill acts as a &quot;thin
wrapper&quot; that is there to perform template argument
deduction, the compiler will optimise away the call to fill all
together, replacing it with the call to filler&lt;&gt;::do_fill,
which does use call_traits.</p>
<h3>Rationale</h3> <h3>Rationale</h3>
<p>The following notes are intended to briefly describe the <p>The following notes are intended to briefly describe the
@ -713,7 +729,7 @@ specialisation).</p>
<hr> <hr>
<p>Revised 18 June 2000</p> <p>Revised 01 September 2000</p>
<p>© Copyright boost.org 2000. Permission to copy, use, modify, <p>© Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this sell and distribute this document is granted provided this

View File

@ -9,6 +9,14 @@
// Crippled version for crippled compilers: // Crippled version for crippled compilers:
// see libs/utility/call_traits.htm // see libs/utility/call_traits.htm
// //
/* Release notes:
01st October 2000:
Fixed call_traits on VC6, using "poor man's partial specialisation",
using ideas taken from "Generative programming" by Krzysztof Czarnecki
& Ulrich Eisenecker.
*/
#ifndef BOOST_OB_CALL_TRAITS_HPP #ifndef BOOST_OB_CALL_TRAITS_HPP
#define BOOST_OB_CALL_TRAITS_HPP #define BOOST_OB_CALL_TRAITS_HPP
@ -22,6 +30,85 @@
namespace boost{ namespace boost{
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
//
// use member templates to emulate
// partial specialisation:
//
namespace detail{
template <class T>
struct standard_call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& param_type;
};
template <class T>
struct simple_call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T param_type;
};
template <class T>
struct reference_call_traits
{
typedef T value_type;
typedef T reference;
typedef T const_reference;
typedef T param_type;
};
template <bool simple, bool reference>
struct call_traits_chooser
{
template <class T>
struct rebind
{
typedef standard_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<true, false>
{
template <class T>
struct rebind
{
typedef simple_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<false, true>
{
template <class T>
struct rebind
{
typedef reference_call_traits<T> type;
};
};
} // namespace detail
template <typename T>
struct call_traits
{
private:
typedef detail::call_traits_chooser<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), is_reference<T>::value> chooser;
typedef typename chooser::template rebind<T> bound_type;
typedef typename bound_type::type call_traits_type;
public:
typedef typename call_traits_type::value_type value_type;
typedef typename call_traits_type::reference reference;
typedef typename call_traits_type::const_reference const_reference;
typedef typename call_traits_type::param_type param_type;
};
#else
//
// sorry call_traits is completely non-functional
// blame your broken compiler:
//
template <typename T> template <typename T>
struct call_traits struct call_traits
{ {
@ -31,6 +118,8 @@ struct call_traits
typedef const T& param_type; typedef const T& param_type;
}; };
#endif // member templates
} }
#endif // BOOST_OB_CALL_TRAITS_HPP #endif // BOOST_OB_CALL_TRAITS_HPP

View File

@ -126,8 +126,7 @@ is always defined as a compile time constant).</p>
<td width="36%"><p align="center">True if T and U are the <td width="36%"><p align="center">True if T and U are the
same type.</p> same type.</p>
</td> </td>
<td width="27%"><p align="center">P</p> <td width="27%">&nbsp; </td>
</td>
</tr> </tr>
<tr> <tr>
<td width="37%"><div align="center"><center><pre>is_convertible&lt;T,U&gt;::value</pre> <td width="37%"><div align="center"><center><pre>is_convertible&lt;T,U&gt;::value</pre>
@ -170,15 +169,13 @@ on a type (see 3.93).</p>
<td valign="top" width="37%"><code>is_const&lt;T&gt;::value</code></td> <td valign="top" width="37%"><code>is_const&lt;T&gt;::value</code></td>
<td valign="top" width="37%">True if type T is top-level <td valign="top" width="37%">True if type T is top-level
const qualified.</td> const qualified.</td>
<td valign="top" width="27%"><p align="center">P</p> <td valign="top" width="27%">&nbsp; </td>
</td>
</tr> </tr>
<tr> <tr>
<td valign="top" width="37%"><code>is_volatile&lt;T&gt;::value</code></td> <td valign="top" width="37%"><code>is_volatile&lt;T&gt;::value</code></td>
<td valign="top" width="37%">True if type T is top-level <td valign="top" width="37%">True if type T is top-level
volatile qualified.</td> volatile qualified.</td>
<td valign="top" width="27%"><p align="center">P</p> <td valign="top" width="27%">&nbsp; </td>
</td>
</tr> </tr>
</table> </table>
@ -348,22 +345,19 @@ as defined by the Standard.&nbsp;</p>
<td valign="top" width="45%">True if T is a regular <td valign="top" width="45%">True if T is a regular
pointer type - including function pointers - but pointer type - including function pointers - but
excluding pointers to member functions (3.9.2 p1 and 8.3.1).</td> excluding pointers to member functions (3.9.2 p1 and 8.3.1).</td>
<td valign="top" width="33%"><p align="center">P</p> <td valign="top" width="33%">&nbsp; </td>
</td>
</tr> </tr>
<tr> <tr>
<td valign="top" width="45%"><code>is_member_pointer&lt;T&gt;::value</code></td> <td valign="top" width="45%"><code>is_member_pointer&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a pointer to a <td valign="top" width="45%">True if T is a pointer to a
non-static class member (3.9.2 p1 and 8.3.1).</td> non-static class member (3.9.2 p1 and 8.3.1).</td>
<td valign="top" width="33%"><p align="center">P</p> <td valign="top" width="33%">&nbsp; </td>
</td>
</tr> </tr>
<tr> <tr>
<td valign="top" width="45%"><code>is_reference&lt;T&gt;::value</code></td> <td valign="top" width="45%"><code>is_reference&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a reference <td valign="top" width="45%">True if T is a reference
type (3.9.2 p1 and 8.3.2).</td> type (3.9.2 p1 and 8.3.2).</td>
<td valign="top" width="33%"><p align="center">P</p> <td valign="top" width="33%">&nbsp; </td>
</td>
</tr> </tr>
<tr> <tr>
<td valign="top" width="45%"><code>is_class&lt;T&gt;::value</code></td> <td valign="top" width="45%"><code>is_class&lt;T&gt;::value</code></td>
@ -607,7 +601,7 @@ familiar standard library algorithms.</p>
<hr> <hr>
<p>Revised 08<sup>th</sup> March 2000</p> <p>Revised 01 September 2000</p>
<p>© Copyright boost.org 2000. Permission to copy, use, modify, <p>© Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this sell and distribute this document is granted provided this