type traits update [added is_convertible and alignment_of]

[SVN r7675]
This commit is contained in:
John Maddock 2000-08-02 10:58:59 +00:00
parent 2086542bfb
commit daf7829ffa
9 changed files with 271 additions and 112 deletions

View File

@ -1,3 +1,11 @@
// boost::compressed_pair test program
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// standalone test program for <boost/call_traits.hpp>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
@ -6,12 +14,7 @@
#include <typeinfo> #include <typeinfo>
#include <boost/call_traits.hpp> #include <boost/call_traits.hpp>
#ifdef __BORLANDC__ #include "type_traits_test.hpp"
// turn off some warnings, the way we do the tests will generate a *lot* of these
// this is a result of the tests not call_traits itself....
#pragma option -w-8004 -w-ccc -w-rch -w-eff -w-aus
#endif
// //
// struct contained models a type that contains a type (for example std::pair) // struct contained models a type that contains a type (for example std::pair)
// arrays are contained by value, and have to be treated as a special case: // arrays are contained by value, and have to be treated as a special case:
@ -178,30 +181,6 @@ struct UDT
bool operator == (const UDT& v){ return v.i_ == i_; } bool operator == (const UDT& v){ return v.i_ == i_; }
}; };
//
// define tests here
unsigned failures = 0;
unsigned test_count = 0;
#define value_test(v, x) ++test_count;\
if(v != x){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#define type_test(v, x) ++test_count;\
if(boost::is_same<v, x>::value == false){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << typeid(boost::is_same<v, x>).name() << "::value is false" << std::endl; }
#else
#define type_test(v, x) ++test_count;\
if(typeid(v) != typeid(x)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; }
#endif
int main() int main()
{ {
checker<UDT> c1; checker<UDT> c1;

View File

@ -5,43 +5,17 @@
// in all copies. This software is provided "as is" without express or implied // in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// standalone test program for <boost/compressed_pair.hpp>
#include <iostream> #include <iostream>
#include <typeinfo> #include <typeinfo>
#include <cassert> #include <cassert>
#include <boost/compressed_pair.hpp> #include <boost/compressed_pair.hpp>
#include "type_traits_test.hpp"
using namespace boost; using namespace boost;
#ifdef __BORLANDC__
#pragma option -w-ccc -w-rch -w-eff -w-aus
#endif
//
// define tests here
unsigned failures = 0;
unsigned test_count = 0;
#define value_test(v, x) ++test_count;\
if(v != x){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
#define value_fail(v, x) ++test_count; ++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#define type_test(v, x) ++test_count;\
if(boost::is_same<v, x>::value == false){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << typeid(boost::is_same<v, x>).name() << "::value is false" << std::endl; }
#else
#define type_test(v, x) ++test_count;\
if(typeid(v) != typeid(x)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; }
#endif
struct empty_POD_UDT{}; struct empty_POD_UDT{};
struct empty_UDT struct empty_UDT
{ {

View File

@ -6,6 +6,9 @@
// See http://www.boost.org for most recent version including documentation. // See http://www.boost.org for most recent version including documentation.
// call_traits: defines typedefs for function usage
// (see libs/utility/call_traits.htm)
/* Release notes: /* Release notes:
23rd July 2000: 23rd July 2000:
Fixed array specialization. (JM) Fixed array specialization. (JM)

View File

@ -6,6 +6,8 @@
// See http://www.boost.org for most recent version including documentation. // See http://www.boost.org for most recent version including documentation.
// compressed_pair: pair that "compresses" empty members
// (see libs/utility/compressed_pair.htm)
// //
// JM changes 25 Jan 2000: // JM changes 25 Jan 2000:
// Removed default arguments from compressed_pair_switch to get // Removed default arguments from compressed_pair_switch to get

View File

@ -7,6 +7,7 @@
// See http://www.boost.org for most recent version including documentation. // See http://www.boost.org for most recent version including documentation.
// //
// Crippled version for crippled compilers: // Crippled version for crippled compilers:
// see libs/utility/call_traits.htm
// //
#ifndef BOOST_OB_CALL_TRAITS_HPP #ifndef BOOST_OB_CALL_TRAITS_HPP
#define BOOST_OB_CALL_TRAITS_HPP #define BOOST_OB_CALL_TRAITS_HPP

View File

@ -5,6 +5,7 @@
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation. // See http://www.boost.org for most recent version including documentation.
// see libs/utility/compressed_pair.hpp
// //
/* Release notes: /* Release notes:
23rd July 2000: 23rd July 2000:

View File

@ -25,6 +25,7 @@ divided up into the following sections:</p>
<pre><a href="#fop">Fundamental type operations</a> <pre><a href="#fop">Fundamental type operations</a>
<a href="#fp">Fundamental type properties</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="#cv">cv-Qualifiers</a>
<code> </code><a href="#ft">Fundamental Types</a> <code> </code><a href="#ft">Fundamental Types</a>
<code> </code><a href="#ct">Compound Types</a> <code> </code><a href="#ct">Compound Types</a>
@ -37,7 +38,7 @@ divided up into the following sections:</p>
<p>Usage: &quot;class_name&lt;T&gt;::type&quot; performs <p>Usage: &quot;class_name&lt;T&gt;::type&quot; performs
indicated transformation on type T.</p> indicated transformation on type T.</p>
<table border="1" cellpadding="7" cellspacing="1" width="624"> <table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr> <tr>
<td valign="top" width="45%"><p align="center">Expression.</p> <td valign="top" width="45%"><p align="center">Expression.</p>
</td> </td>
@ -108,39 +109,75 @@ indicated transformation on type T.</p>
indicated property is true, false otherwise. (Note that class_name&lt;T&gt;::value indicated property is true, false otherwise. (Note that class_name&lt;T&gt;::value
is always defined as a compile time constant).</p> 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&lt;T,U&gt;::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%"><p align="center">P</p>
</td>
</tr>
<tr>
<td width="37%"><div align="center"><center><pre>is_convertible&lt;T,U&gt;::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%">&nbsp;</td>
</tr>
<tr>
<td width="37%"><div align="center"><center><pre>alignment_of&lt;T&gt;::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%">&nbsp;</td>
</tr>
</table>
<p>&nbsp;</p>
<h3><a name="cv"></a>cv-Qualifiers</h3> <h3><a name="cv"></a>cv-Qualifiers</h3>
<p>The following classes determine what cv-qualifiers are present <p>The following classes determine what cv-qualifiers are present
on a type (see 3.93).</p> on a type (see 3.93).</p>
<table border="1" cellpadding="7" cellspacing="1" width="624"> <table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr> <tr>
<td valign="top" width="45%"><p align="center">Expression.</p> <td valign="top" width="37%"><p align="center">Expression.</p>
</td> </td>
<td valign="top" width="45%"><p align="center">Description.</p> <td valign="top" width="37%"><p align="center">Description.</p>
</td> </td>
<td valign="top" width="33%"><p align="center">Compiler.</p> <td valign="top" width="27%"><p align="center">Compiler.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td valign="top" width="45%"><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="45%">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="33%"><p align="center">P</p> <td valign="top" width="27%"><p align="center">P</p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td valign="top" width="45%"><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="45%">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="33%"><p align="center">P</p> <td valign="top" width="27%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_same&lt;T,U&gt;::value</code></td>
<td valign="top" width="45%">True if T and U are the same
type.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td> </td>
</tr> </tr>
</table> </table>
@ -152,7 +189,7 @@ on a type (see 3.93).</p>
<p>The following will only ever be true for cv-unqualified types; <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> these are closely based on the section 3.9 of the C++ Standard.</p>
<table border="1" cellpadding="7" cellspacing="1" width="624"> <table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr> <tr>
<td valign="top" width="45%"><p align="center">Expression.</p> <td valign="top" width="45%"><p align="center">Expression.</p>
</td> </td>
@ -291,7 +328,7 @@ these are closely based on the section 3.9 of the C++ Standard.</p>
<p>The following will only ever be true for cv-unqualified types, <p>The following will only ever be true for cv-unqualified types,
as defined by the Standard.&nbsp;</p> as defined by the Standard.&nbsp;</p>
<table border="1" cellpadding="7" cellspacing="1" width="624"> <table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr> <tr>
<td valign="top" width="45%"><p align="center">Expression</p> <td valign="top" width="45%"><p align="center">Expression</p>
</td> </td>
@ -365,7 +402,7 @@ as defined by the Standard.&nbsp;</p>
is true then <code>class_name&lt;cv-qualified-T&gt;::value</code> is true then <code>class_name&lt;cv-qualified-T&gt;::value</code>
will also be true.</p> will also be true.</p>
<table border="1" cellpadding="7" cellspacing="1" width="624"> <table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr> <tr>
<td valign="top" width="45%"><p align="center">Expression</p> <td valign="top" width="45%"><p align="center">Expression</p>
</td> </td>
@ -420,9 +457,10 @@ will also be true.</p>
or class. If the compiler implements the &quot;zero sized or class. If the compiler implements the &quot;zero sized
empty base classes&quot; optimisation, then is_empty will empty base classes&quot; optimisation, then is_empty will
correctly guess whether T is empty. Relies upon is_class correctly guess whether T is empty. Relies upon is_class
to determine whether T is a class type - as a result will to determine whether T is a class type. Screens out enum
not compile when passed an enumerated type unless there types by using is_convertible&lt;T,int&gt;, this means
is compiler support for is_enum.</td> 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 valign="top" width="33%"><p align="center">PCD</p>
</td> </td>
</tr> </tr>
@ -582,7 +620,7 @@ Hinnant and John Maddock.</p>
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John <p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
Maddock</a>, the latest version of this file can be found at <a 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 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> discussion list at <a href="http://www.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
</body> </body>
</html> </html>

View File

@ -4,7 +4,11 @@
// in all copies. This software is provided "as is" without express or implied // in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// standalone test program for <boost/type_traits.hpp>
/* Release notes: /* Release notes:
31st July 2000:
Added extra tests for is_empty, is_convertible, alignment_of.
23rd July 2000: 23rd July 2000:
Removed all call_traits tests to call_traits_test.cpp Removed all call_traits tests to call_traits_test.cpp
Removed all compressed_pair tests to compressed_pair_tests.cpp Removed all compressed_pair tests to compressed_pair_tests.cpp
@ -16,37 +20,10 @@
#include <typeinfo> #include <typeinfo>
#include <boost/type_traits.hpp> #include <boost/type_traits.hpp>
#include "type_traits_test.hpp"
using namespace boost; using namespace boost;
#ifdef __BORLANDC__
#pragma option -w-ccc -w-rch -w-eff -w-aus
#endif
//
// define tests here
unsigned failures = 0;
unsigned test_count = 0;
#define value_test(v, x) ++test_count;\
if(v != x){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
#define value_fail(v, x) ++test_count; ++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#define type_test(v, x) ++test_count;\
if(is_same<v, x>::value == false){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << typeid(is_same<v, x>).name() << "::value is false" << std::endl; }
#else
#define type_test(v, x) ++test_count;\
if(typeid(v) != typeid(x)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; }
#endif
// Since there is no compiler support, we should specialize: // Since there is no compiler support, we should specialize:
// is_enum for all enumerations (is_enum implies is_POD) // is_enum for all enumerations (is_enum implies is_POD)
// is_union for all unions // is_union for all unions
@ -160,6 +137,33 @@ template <> struct is_POD<empty_POD_union_UDT>
} }
#endif #endif
class Base { };
class Deriverd : public Base { };
class NonDerived { };
enum enum1
{
one_,two_
};
enum enum2
{
three_,four_
};
struct VB
{
virtual ~VB(){};
};
struct VD : VB
{
~VD(){};
};
// Steve: All comments that I (Steve Cleary) have added below are prefixed with // Steve: All comments that I (Steve Cleary) have added below are prefixed with
// "Steve:" The failures that BCB4 has on the tests are due to Borland's // "Steve:" The failures that BCB4 has on the tests are due to Borland's
// not considering cv-qual's as a part of the type -- they are considered // not considering cv-qual's as a part of the type -- they are considered
@ -530,6 +534,57 @@ int main()
value_test(false, is_POD<empty_UDT>::value) value_test(false, is_POD<empty_UDT>::value)
value_test(true, is_POD<enum_UDT>::value) value_test(true, is_POD<enum_UDT>::value)
value_test(true, (boost::is_convertible<Deriverd,Base>::value));
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
value_test(true, (boost::is_convertible<Base,Base>::value));
value_test(false, (boost::is_convertible<Base,Deriverd>::value));
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
value_test(false, (boost::is_convertible<NonDerived,Base>::value));
//value_test(false, (boost::is_convertible<boost::noncopyable, boost::noncopyable>::value));
value_test(true, (boost::is_convertible<float,int>::value));
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
value_test(false, (boost::is_convertible<float,void>::value));
value_test(false, (boost::is_convertible<void,float>::value));
value_test(true, (boost::is_convertible<void,void>::value));
#endif
value_test(true, (boost::is_convertible<enum1, int>::value));
value_test(true, (boost::is_convertible<Deriverd*, Base*>::value));
value_test(false, (boost::is_convertible<Base*, Deriverd*>::value));
value_test(true, (boost::is_convertible<Deriverd&, Base&>::value));
value_test(false, (boost::is_convertible<Base&, Deriverd&>::value));
value_test(true, (boost::is_convertible<const Deriverd*, const Base*>::value));
value_test(false, (boost::is_convertible<const Base*, const Deriverd*>::value));
value_test(true, (boost::is_convertible<const Deriverd&, const Base&>::value));
value_test(false, (boost::is_convertible<const Base&, const Deriverd&>::value));
value_test(false, (boost::is_convertible<const int *, int*>::value));
value_test(false, (boost::is_convertible<const int&, int&>::value));
value_test(false, (boost::is_convertible<int*, int[2]>::value));
value_test(false, (boost::is_convertible<const int*, int[3]>::value));
value_test(true, (boost::is_convertible<const int&, int>::value));
value_test(true, (boost::is_convertible<int(&)[4], const int*>::value));
value_test(true, (boost::is_convertible<int(&)(int), int(*)(int)>::value));
value_test(true, (boost::is_convertible<int *, const int*>::value));
value_test(true, (boost::is_convertible<int&, const int&>::value));
value_test(true, (boost::is_convertible<int[2], int*>::value));
value_test(true, (boost::is_convertible<int[2], const int*>::value));
value_test(false, (boost::is_convertible<const int[2], int*>::value));
align_test(int);
align_test(char);
align_test(double);
align_test(int[4]);
align_test(int(*)(int));
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
align_test(char&);
align_test(char (&)(int));
align_test(char(&)[4]);
#endif
align_test(int*);
//align_test(const int);
align_test(VB);
align_test(VD);
std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit"; std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit";
std::cin.get(); std::cin.get();
return failures; return failures;

106
type_traits_test.hpp Normal file
View File

@ -0,0 +1,106 @@
// boost::compressed_pair test program
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// common test code for type_traits_test.cpp/call_traits_test.cpp/compressed_pair_test.cpp
#ifndef BOOST_TYPE_TRAITS_TEST_HPP
#define BOOST_TYPE_TRAITS_TEST_HPP
//
// this one is here just to suppress warnings:
//
template <class T>
bool do_compare(T i, T j)
{
return i == j;
}
//
// this one is to verify that a constant is indeed a
// constant-integral-expression:
//
template <int>
struct ct_checker
{
};
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2(X, Y) X ## Y
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define value_test(v, x) ++test_count;\
typedef ct_checker<(x)> BOOST_JOIN(this_is_a_compile_time_check_, __LINE__);\
if(!do_compare((int)v,(int)x)){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
#define value_fail(v, x) ++test_count; ++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#define type_test(v, x) ++test_count;\
if(do_compare(boost::is_same<v, x>::value, false)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << typeid(boost::is_same<v, x>).name() << "::value is false" << std::endl; }
#else
#define type_test(v, x) ++test_count;\
if(typeid(v) != typeid(x)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; }
#endif
template <class T>
struct test_align
{
struct padded
{
char c;
T t;
};
static void do_it()
{
padded p;
unsigned a = reinterpret_cast<char*>(&(p.t)) - reinterpret_cast<char*>(&p);
value_test(a, boost::alignment_of<T>::value);
}
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct test_align<T&>
{
static void do_it()
{
//
// we can't do the usual test because we can't take the address
// of a reference, so check that the result is the same as for a
// pointer type instead:
value_test(boost::alignment_of<T*>::value, boost::alignment_of<T&>::value);
}
};
#endif
#define align_test(T) test_align<T>::do_it()
//
// define tests here
unsigned failures = 0;
unsigned test_count = 0;
//
// turn off some warnings:
#ifdef __BORLANDC__
#pragma option -w-8004
#endif
#ifdef BOOST_MSVC
#pragma warning (disable: 4018)
#endif
#endif // BOOST_TYPE_TRAITS_TEST_HPP