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
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>
right. </p>
<p>Note that for compilers that do not support either partial
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">
<tr>
@ -569,7 +575,9 @@ std::pair&lt;
degraded to pointers if the deduced types are arrays, similar
situations occur in the standard binders and adapters: in
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>
@ -632,6 +640,14 @@ 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>
<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>
<p>The following notes are intended to briefly describe the
@ -713,7 +729,7 @@ specialisation).</p>
<hr>
<p>Revised 18 June 2000</p>
<p>Revised 01 September 2000</p>
<p>© Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this

View File

@ -9,6 +9,14 @@
// Crippled version for crippled compilers:
// 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
#define BOOST_OB_CALL_TRAITS_HPP
@ -22,6 +30,85 @@
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>
struct call_traits
{
@ -31,6 +118,8 @@ struct call_traits
typedef const T& param_type;
};
#endif // member templates
}
#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
same type.</p>
</td>
<td width="27%"><p align="center">P</p>
</td>
<td width="27%">&nbsp; </td>
</tr>
<tr>
<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%">True if type T is top-level
const qualified.</td>
<td valign="top" width="27%"><p align="center">P</p>
</td>
<td valign="top" width="27%">&nbsp; </td>
</tr>
<tr>
<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
volatile qualified.</td>
<td valign="top" width="27%"><p align="center">P</p>
</td>
<td valign="top" width="27%">&nbsp; </td>
</tr>
</table>
@ -348,22 +345,19 @@ as defined by the Standard.&nbsp;</p>
<td valign="top" width="45%">True if T is a regular
pointer type - including function pointers - but
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>
<td valign="top" width="33%">&nbsp; </td>
</tr>
<tr>
<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
non-static class member (3.9.2 p1 and 8.3.1).</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
<td valign="top" width="33%">&nbsp; </td>
</tr>
<tr>
<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
type (3.9.2 p1 and 8.3.2).</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
<td valign="top" width="33%">&nbsp; </td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_class&lt;T&gt;::value</code></td>
@ -607,7 +601,7 @@ familiar standard library algorithms.</p>
<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,
sell and distribute this document is granted provided this