mirror of
https://github.com/boostorg/utility.git
synced 2025-07-29 20:37:32 +02:00
Join ralf_grosse_kunstleve with HEAD
[SVN r9444]
This commit is contained in:
@ -19,8 +19,11 @@
|
||||
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits.hpp>
|
||||
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/object_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_SAME_TRAITS_HPP
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_CALL_TRAITS_HPP
|
||||
#include <boost/call_traits.hpp>
|
||||
@ -422,3 +425,4 @@ swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
|
||||
|
||||
|
||||
|
@ -24,8 +24,11 @@
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits.hpp>
|
||||
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
@ -7,6 +7,16 @@
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
|
||||
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
|
||||
// on MSVC. Reordered some #ifdefs for coherency.
|
||||
// (David Abrahams)
|
||||
// 13 Feb 2001 Test new VC6 workarounds (David Abrahams)
|
||||
// 11 Feb 2001 Final fixes for Borland (David Abrahams)
|
||||
// 11 Feb 2001 Some fixes for Borland get it closer on that compiler
|
||||
// (David Abrahams)
|
||||
// 07 Feb 2001 More comprehensive testing; factored out static tests for
|
||||
// better reuse (David Abrahams)
|
||||
// 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a
|
||||
// reference type from operator* (David Abrahams)
|
||||
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
|
||||
@ -21,105 +31,162 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
struct my_iterator
|
||||
: public boost::forward_iterator_helper<my_iterator, const char, long>
|
||||
// An iterator for which we can get traits.
|
||||
struct my_iterator1
|
||||
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
|
||||
{
|
||||
my_iterator(const char* p) : m_p(p) {}
|
||||
my_iterator1(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator& rhs) const
|
||||
bool operator==(const my_iterator1& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator& operator++() { ++this->m_p; return *this; }
|
||||
my_iterator1& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Test difference_type and iterator_category
|
||||
// Used to prove that we don't require std::iterator<> in the hierarchy under
|
||||
// MSVC6, and that we can compute all the traits for a standard-conforming UDT
|
||||
// iterator.
|
||||
struct my_iterator2
|
||||
: boost::equality_comparable<my_iterator2
|
||||
, boost::incrementable<my_iterator2
|
||||
, boost::dereferenceable<my_iterator2,const char*> > >
|
||||
{
|
||||
typedef char value_type;
|
||||
typedef long difference_type;
|
||||
typedef const char* pointer;
|
||||
typedef const char& reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
my_iterator2(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator2& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
// istream_iterator (forward_iterator_tag, ptrdiff_t)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::istream_iterator<int> >::iterator_category,
|
||||
std::input_iterator_tag
|
||||
>::value));
|
||||
my_iterator2& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::istream_iterator<int> >::difference_type,
|
||||
std::ptrdiff_t
|
||||
>::value));
|
||||
// Used to prove that we're not overly confused by the existence of
|
||||
// std::iterator<> in the hierarchy under MSVC6 - we should find that
|
||||
// boost::detail::iterator_traits<my_iterator3>::difference_type is int.
|
||||
struct my_iterator3 : my_iterator1
|
||||
{
|
||||
typedef int difference_type;
|
||||
my_iterator3(const char* p) : my_iterator1(p) {}
|
||||
};
|
||||
|
||||
// ostream_iterator (output_iterator_tag, void)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::ostream_iterator<int> >::iterator_category,
|
||||
std::output_iterator_tag
|
||||
>::value));
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_portable_tests
|
||||
{
|
||||
// Unfortunately, the VC6 standard library doesn't supply these :(
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::pointer,
|
||||
pointer
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::reference,
|
||||
reference
|
||||
>::value));
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::ostream_iterator<int> >::difference_type,
|
||||
void
|
||||
>::value));
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct portable_tests
|
||||
{
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::difference_type,
|
||||
difference_type
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::iterator_category,
|
||||
category
|
||||
>::value));
|
||||
};
|
||||
|
||||
// Test iterator_traits
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct input_iterator_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::value_type,
|
||||
value_type
|
||||
>::value));
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_pointer_test
|
||||
: input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct maybe_pointer_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
|
||||
istream_iterator_test;
|
||||
|
||||
//
|
||||
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
|
||||
typedef ::std::char_traits<char>::off_type distance;
|
||||
non_pointer_test<std::ostream_iterator<int>,int,
|
||||
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
||||
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
int, void, void, void, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#else
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
void, void, void, void, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#endif
|
||||
|
||||
// list<int>::iterator (bidirectional_iterator_tag, ptrdiff_t)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::list<int>::iterator>::iterator_category,
|
||||
std::bidirectional_iterator_tag
|
||||
>::value));
|
||||
|
||||
#ifdef __KCC
|
||||
typedef long std_list_diff_type;
|
||||
#else
|
||||
typedef std::ptrdiff_t std_list_diff_type;
|
||||
#endif
|
||||
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
|
||||
list_iterator_test;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::list<int>::iterator>::difference_type,
|
||||
std_list_diff_type
|
||||
>::value));
|
||||
maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
vector_iterator_test;
|
||||
|
||||
// vector<int>::iterator (random_access_iterator_tag, ptrdiff_t)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::vector<int>::iterator>::iterator_category,
|
||||
std::random_access_iterator_tag
|
||||
>::value));
|
||||
maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
int_pointer_test;
|
||||
|
||||
non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator1_test;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<std::vector<int>::iterator>::difference_type,
|
||||
std::ptrdiff_t
|
||||
>::value));
|
||||
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator2_test;
|
||||
|
||||
// int* (random_access_iterator_tag, ptrdiff_t)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<int*>::iterator_category,
|
||||
std::random_access_iterator_tag
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<int*>::difference_type,
|
||||
std::ptrdiff_t
|
||||
>::value));
|
||||
|
||||
// my_iterator (forward_iterator_tag, long)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<my_iterator>::iterator_category,
|
||||
std::forward_iterator_tag
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::detail::iterator_traits<my_iterator>::difference_type,
|
||||
long
|
||||
>::value));
|
||||
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator3_test;
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -135,7 +202,9 @@ int main()
|
||||
assert(boost::detail::distance(v.begin(), v.end()) == length);
|
||||
|
||||
assert(boost::detail::distance(&ints[0], ints + length) == length);
|
||||
assert(boost::detail::distance(my_iterator(chars), my_iterator(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
620
type_traits.htm
620
type_traits.htm
@ -1,620 +0,0 @@
|
||||
<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>Type Traits</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
|
||||
|
||||
<h1><img src="../../c++boost.gif" width="276" height="86">Header
|
||||
<<a href="../../boost/detail/type_traits.hpp">boost/type_traits.hpp</a>></h1>
|
||||
|
||||
<p>The contents of <boost/type_traits.hpp> are declared in
|
||||
namespace boost.</p>
|
||||
|
||||
<p>The file <<a href="../../boost/detail/type_traits.hpp">boost/type_traits.hpp</a>>
|
||||
contains various template classes that describe the fundamental
|
||||
properties of a type; each class represents a single type
|
||||
property or a single type transformation. This documentation is
|
||||
divided up into the following sections:</p>
|
||||
|
||||
<pre><a href="#fop">Fundamental type operations</a>
|
||||
<a href="#fp">Fundamental type properties</a>
|
||||
<a href="#misc">Miscellaneous</a>
|
||||
<code> </code><a href="#cv">cv-Qualifiers</a>
|
||||
<code> </code><a href="#ft">Fundamental Types</a>
|
||||
<code> </code><a href="#ct">Compound Types</a>
|
||||
<code> </code><a href="#ot">Object/Scalar Types</a>
|
||||
<a href="#cs">Compiler Support Information</a>
|
||||
<a href="#ec">Example Code</a></pre>
|
||||
|
||||
<h2><a name="fop"></a>Fundamental type operations</h2>
|
||||
|
||||
<p>Usage: "class_name<T>::type" performs
|
||||
indicated transformation on type T.</p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="100%">
|
||||
<tr>
|
||||
<td valign="top" width="45%"><p align="center">Expression.</p>
|
||||
</td>
|
||||
<td valign="top" width="45%"><p align="center">Description.</p>
|
||||
</td>
|
||||
<td valign="top" width="33%"><p align="center">Compiler.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>remove_volatile<T>::type</code></td>
|
||||
<td valign="top" width="45%">Creates a type the same as T
|
||||
but with any top level volatile qualifier removed. For
|
||||
example "volatile int" would become "int".</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>remove_const<T>::type</code></td>
|
||||
<td valign="top" width="45%">Creates a type the same as T
|
||||
but with any top level const qualifier removed. For
|
||||
example "const int" would become "int".</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>remove_cv<T>::type</code></td>
|
||||
<td valign="top" width="45%">Creates a type the same as T
|
||||
but with any top level cv-qualifiers removed. For example
|
||||
"const int" would become "int", and
|
||||
"volatile double" would become "double".</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>remove_reference<T>::type</code></td>
|
||||
<td valign="top" width="45%">If T is a reference type
|
||||
then removes the reference, otherwise leaves T unchanged.
|
||||
For example "int&" becomes "int"
|
||||
but "int*" remains unchanged.</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>add_reference<T>::type</code></td>
|
||||
<td valign="top" width="45%">If T is a reference type
|
||||
then leaves T unchanged, otherwise converts T to a
|
||||
reference type. For example "int&" remains
|
||||
unchanged, but "double" becomes "double&".</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>remove_bounds<T>::type</code></td>
|
||||
<td valign="top" width="45%">If T is an array type then
|
||||
removes the top level array qualifier from T, otherwise
|
||||
leaves T unchanged. For example "int[2][3]"
|
||||
becomes "int[3]".</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="fp"></a>Fundamental type properties</h2>
|
||||
|
||||
<p>Usage: "class_name<T>::value" is true if
|
||||
indicated property is true, false otherwise. (Note that class_name<T>::value
|
||||
is always defined as a compile time constant).</p>
|
||||
|
||||
<h3><a name="misc"></a>Miscellaneous</h3>
|
||||
|
||||
<table border="1" cellspacing="1" width="100%">
|
||||
<tr>
|
||||
<td width="37%"><p align="center">Expression</p>
|
||||
</td>
|
||||
<td width="36%"><p align="center">Description</p>
|
||||
</td>
|
||||
<td width="27%"><p align="center">Compiler</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="37%"><div align="center"><center><pre><code>is_same<T,U>::value</code></pre>
|
||||
</center></div></td>
|
||||
<td width="36%"><p align="center">True if T and U are the
|
||||
same type.</p>
|
||||
</td>
|
||||
<td width="27%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="37%"><div align="center"><center><pre>is_convertible<T,U>::value</pre>
|
||||
</center></div></td>
|
||||
<td width="36%"><p align="center">True if type T is
|
||||
convertible to type U.</p>
|
||||
</td>
|
||||
<td width="27%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="37%"><div align="center"><center><pre>alignment_of<T>::value</pre>
|
||||
</center></div></td>
|
||||
<td width="36%"><p align="center">An integral value
|
||||
representing the minimum alignment requirements of type T
|
||||
(strictly speaking defines a multiple of the type's
|
||||
alignment requirement; for all compilers tested so far
|
||||
however it does return the actual alignment).</p>
|
||||
</td>
|
||||
<td width="27%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h3><a name="cv"></a>cv-Qualifiers</h3>
|
||||
|
||||
<p>The following classes determine what cv-qualifiers are present
|
||||
on a type (see 3.93).</p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="100%">
|
||||
<tr>
|
||||
<td valign="top" width="37%"><p align="center">Expression.</p>
|
||||
</td>
|
||||
<td valign="top" width="37%"><p align="center">Description.</p>
|
||||
</td>
|
||||
<td valign="top" width="27%"><p align="center">Compiler.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="37%"><code>is_const<T>::value</code></td>
|
||||
<td valign="top" width="37%">True if type T is top-level
|
||||
const qualified.</td>
|
||||
<td valign="top" width="27%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="37%"><code>is_volatile<T>::value</code></td>
|
||||
<td valign="top" width="37%">True if type T is top-level
|
||||
volatile qualified.</td>
|
||||
<td valign="top" width="27%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h3><a name="ft"></a>Fundamental Types</h3>
|
||||
|
||||
<p>The following will only ever be true for cv-unqualified types;
|
||||
these are closely based on the section 3.9 of the C++ Standard.</p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="100%">
|
||||
<tr>
|
||||
<td valign="top" width="45%"><p align="center">Expression.</p>
|
||||
</td>
|
||||
<td valign="top" width="45%"><p align="center">Description.</p>
|
||||
</td>
|
||||
<td valign="top" width="33%"><p align="center">Compiler.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_void<T>::value</code></td>
|
||||
<td valign="top" width="45%">True only if T is void.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_unsigned_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True only if T is one of the
|
||||
standard unsigned integral types (3.9.1 p3) - unsigned
|
||||
char, unsigned short, unsigned int, and unsigned long.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_signed_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True only if T is one of the
|
||||
standard signed integral types (3.9.1 p2) - signed char,
|
||||
short, int, and long.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a standard
|
||||
integral type(3.9.1 p7) - T is either char, wchar_t, bool
|
||||
or either is_standard_signed_integral<T>::value or
|
||||
is_standard_integral<T>::value is true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_float<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is one of the
|
||||
standard floating point types(3.9.1 p8) - float, double
|
||||
or long double.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_arithmetic<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a standard
|
||||
arithmetic type(3.9.1 p8) - implies is_standard_integral
|
||||
or is_standard_float is true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_fundamental<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a standard
|
||||
arithmetic type or if T is void.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_extension_unsigned_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True for compiler specific
|
||||
unsigned integral types.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_extension_signed_integral<T>>:value</code></td>
|
||||
<td valign="top" width="45%">True for compiler specific
|
||||
signed integral types.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_extension_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_extension_unsigned_integral<T>::value
|
||||
or is_extension_signed_integral<T>::value is true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_extension_float<T>::value</code></td>
|
||||
<td valign="top" width="45%">True for compiler specific
|
||||
floating point types.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_extension_arithmetic<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_extension_integral<T>::value
|
||||
or is_extension_float<T>::value are true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code> is_extension_fundamental<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_extension_arithmetic<T>::value
|
||||
or is_void<T>::value are true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code> is_unsigned_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_standard_unsigned_integral<T>::value
|
||||
or is_extention_unsigned_integral<T>::value are
|
||||
true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_signed_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_standard_signed_integral<T>::value
|
||||
or is_extention_signed_integral<T>>::value are
|
||||
true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_integral<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_standard_integral<T>::value
|
||||
or is_extention_integral<T>::value are true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_float<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_standard_float<T>::value
|
||||
or is_extention_float<T>::value are true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_arithmetic<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_integral<T>::value
|
||||
or is_float<T>::value are true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_fundamental<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if either is_arithmetic<T>::value
|
||||
or is_void<T>::value are true.</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h3><a name="ct"></a>Compound Types</h3>
|
||||
|
||||
<p>The following will only ever be true for cv-unqualified types,
|
||||
as defined by the Standard. </p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="100%">
|
||||
<tr>
|
||||
<td valign="top" width="45%"><p align="center">Expression</p>
|
||||
</td>
|
||||
<td valign="top" width="45%"><p align="center">Description</p>
|
||||
</td>
|
||||
<td valign="top" width="33%"><p align="center">Compiler</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_array<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is an array type.</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_pointer<T>::value</code></td>
|
||||
<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%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_member_pointer<T>::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%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_reference<T>::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%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_class<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a class or
|
||||
struct type.</td>
|
||||
<td valign="top" width="33%"><p align="center">PD</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_union<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a union type.</td>
|
||||
<td valign="top" width="33%"><p align="center">C</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_enum<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is an enumerator
|
||||
type.</td>
|
||||
<td valign="top" width="33%"><p align="center">C</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_compound<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is any of the
|
||||
above compound types.</td>
|
||||
<td valign="top" width="33%"><p align="center">PD</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h3><a name="ot"></a>Object/Scalar Types</h3>
|
||||
|
||||
<p>The following ignore any top level cv-qualifiers: if <code>class_name<T>::value</code>
|
||||
is true then <code>class_name<cv-qualified-T>::value</code>
|
||||
will also be true.</p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="100%">
|
||||
<tr>
|
||||
<td valign="top" width="45%"><p align="center">Expression</p>
|
||||
</td>
|
||||
<td valign="top" width="45%"><p align="center">Description</p>
|
||||
</td>
|
||||
<td valign="top" width="33%"><p align="center">Compiler</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_object<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is not a reference
|
||||
type, or a (possibly cv-qualified) void type.</td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_standard_scalar<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a standard
|
||||
arithmetic type, an enumerated type, a pointer or a
|
||||
member pointer.</td>
|
||||
<td valign="top" width="33%"><p align="center">PD</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_extension_scalar<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is an extentions
|
||||
arithmetic type, an enumerated type, a pointer or a
|
||||
member pointer.</td>
|
||||
<td valign="top" width="33%"><p align="center">PD</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_scalar<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is an arithmetic
|
||||
type, an enumerated type, a pointer or a member pointer.</td>
|
||||
<td valign="top" width="33%"><p align="center">PD</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_POD<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a "Plain
|
||||
Old Data" type (see 3.9 p2&p3). Note that
|
||||
although this requires compiler support to be correct in
|
||||
all cases, if T is a scalar or an array of scalars then
|
||||
we can correctly define T as a POD.</td>
|
||||
<td valign="top" width="33%"><p align="center">PC</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_empty<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is an empty struct
|
||||
or class. If the compiler implements the "zero sized
|
||||
empty base classes" optimisation, then is_empty will
|
||||
correctly guess whether T is empty. Relies upon is_class
|
||||
to determine whether T is a class type. Screens out enum
|
||||
types by using is_convertible<T,int>, this means
|
||||
that empty classes that overload operator int(), will not
|
||||
be classified as empty.</td>
|
||||
<td valign="top" width="33%"><p align="center">PCD</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>has_trivial_constructor<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T has a trivial
|
||||
default constructor - that is T() is equivalent to memset.</td>
|
||||
<td valign="top" width="33%"><p align="center">PC</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>has_trivial_copy<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T has a trivial copy
|
||||
constructor - that is T(const T&) is equivalent to
|
||||
memcpy.</td>
|
||||
<td valign="top" width="33%"><p align="center">PC</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>has_trivial_assign<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T has a trivial
|
||||
assignment operator - that is if T::operator=(const T&)
|
||||
is equivalent to memcpy.</td>
|
||||
<td valign="top" width="33%"><p align="center">PC</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>has_trivial_destructor<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T has a trivial
|
||||
destructor - that is if T::~T() has no effect.</td>
|
||||
<td valign="top" width="33%"><p align="center">PC</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="cs"></a>Compiler Support Information</h2>
|
||||
|
||||
<p>The legends used in the tables above have the following
|
||||
meanings:</p>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="480">
|
||||
<tr>
|
||||
<td valign="top" width="50%"><p align="center">P</p>
|
||||
</td>
|
||||
<td valign="top" width="90%">Denotes that the class
|
||||
requires support for partial specialisation of class
|
||||
templates to work correctly.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><p align="center">C</p>
|
||||
</td>
|
||||
<td valign="top" width="90%">Denotes that direct compiler
|
||||
support for that traits class is required.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><p align="center">D</p>
|
||||
</td>
|
||||
<td valign="top" width="90%">Denotes that the traits
|
||||
class is dependent upon a class that requires direct
|
||||
compiler support.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<p>For those classes that are marked with a D or C, if compiler
|
||||
support is not provided, this type trait may return "false"
|
||||
when the correct value is actually "true". The single
|
||||
exception to this rule is "is_class", which attempts to
|
||||
guess whether or not T is really a class, and may return "true"
|
||||
when the correct value is actually "false". This can
|
||||
happen if: T is a union, T is an enum, or T is a compiler-supplied
|
||||
scalar type that is not specialised for in these type traits.</p>
|
||||
|
||||
<p><i>If there is no compiler support</i>, to ensure that these
|
||||
traits <i>always</i> return the correct values, specialise 'is_enum'
|
||||
for each user-defined enumeration type, 'is_union' for each user-defined
|
||||
union type, 'is_empty' for each user-defined empty composite type,
|
||||
and 'is_POD' for each user-defined POD type. The 'has_*' traits
|
||||
should also be specialized if the user-defined type has those
|
||||
traits and is <i>not</i> a POD.</p>
|
||||
|
||||
<p>The following rules are automatically enforced:</p>
|
||||
|
||||
<p>is_enum implies is_POD</p>
|
||||
|
||||
<p>is_POD implies has_*</p>
|
||||
|
||||
<p>This means, for example, if you have an empty POD-struct, just
|
||||
specialize is_empty and is_POD, which will cause all the has_* to
|
||||
also return true.</p>
|
||||
|
||||
<h2><a name="ec"></a>Example code</h2>
|
||||
|
||||
<p>Type-traits comes with two sample programs: <a
|
||||
href="type_traits_test.cpp">type_traits_test.cpp</a> tests the
|
||||
type traits classes - mostly this is a test of your compiler's
|
||||
support for the concepts used in the type traits implementation,
|
||||
while <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>
|
||||
uses the type traits classes to "optimise" some
|
||||
familiar standard library algorithms.</p>
|
||||
|
||||
<p>There are four algorithm examples in algo_opt_examples.cpp:</p>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="638">
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>opt::copy</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%">If the copy operation can be
|
||||
performed using memcpy then does so, otherwise uses a
|
||||
regular element by element copy (<i>c.f.</i> std::copy).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>opt::fill</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%">If the fill operation can be
|
||||
performed by memset, then does so, otherwise uses a
|
||||
regular element by element assign. Also uses call_traits
|
||||
to optimise how the parameters can be passed (<i>c.f.</i>
|
||||
std::fill).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>opt::destroy_array</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%">If the type in the array has
|
||||
a trivial destructor then does nothing, otherwise calls
|
||||
destructors for all elements in the array - this
|
||||
algorithm is the reverse of std::uninitialized_copy / std::uninitialized_fill.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>opt::iter_swap</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%">Determines whether the
|
||||
iterator is a proxy-iterator: if it is then does a "slow
|
||||
and safe" swap, otherwise calls std::swap on the
|
||||
assumption that std::swap may be specialised for the
|
||||
iterated type.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised 01 September 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>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user