Compare commits

..

14 Commits

Author SHA1 Message Date
Ralf W. Grosse-Kunstleve
df2ef006c7 Join ralf_grosse_kunstleve with HEAD
[SVN r9444]
2001-03-05 20:01:01 +00:00
nobody
22d30b566b This commit was manufactured by cvs2svn to create branch
'unlabeled-1.1.2'.

[SVN r9387]
2001-03-03 02:54:02 +00:00
nobody
4476a85d55 This commit was manufactured by cvs2svn to create branch
'unlabeled-1.1.2'.

[SVN r9304]
2001-02-21 08:01:53 +00:00
nobody
f02dc90bfc This commit was manufactured by cvs2svn to create branch
'unlabeled-1.1.2'.

[SVN r8787]
2001-01-27 17:35:01 +00:00
Dave Abrahams
6caf7d4d5a Initial checkin
[SVN r8757]
2001-01-24 18:36:52 +00:00
Dave Abrahams
98e87c8afb Added test for wchar_t
[SVN r8748]
2001-01-24 01:48:01 +00:00
Dave Abrahams
d9e0f80d50 Now statically selecting a test for signed numbers to avoid warnings with fancy
compilers. Added commentary and additional dumping of traits data for tested
types.


[SVN r8746]
2001-01-24 01:40:22 +00:00
Jeremy Siek
6396fdb5ff added filter iterator test
[SVN r8736]
2001-01-23 19:10:03 +00:00
Jens Maurer
2470b53373 minor fix: move "static" storage specifier to the front of a declaration
[SVN r8714]
2001-01-22 21:11:35 +00:00
Jeremy Siek
16334e92ca added KAI C++ type for std::list::difference_type
[SVN r8709]
2001-01-22 16:52:36 +00:00
Dave Abrahams
c22d98a8ec Quick fix to my_iterator, which wasn't returning a reference type from operator*
[SVN r8705]
2001-01-22 05:03:48 +00:00
Dave Abrahams
28617afbb9 Initial checkin
[SVN r8702]
2001-01-22 04:08:29 +00:00
Jeremy Siek
0c3bc42bec new files
[SVN r8685]
2001-01-21 20:12:32 +00:00
Dave Abrahams
e3d9745df1 Initial Checkin
[SVN r8676]
2001-01-21 06:02:08 +00:00
9 changed files with 710 additions and 659 deletions

263
counting_iterator_test.cpp Normal file
View File

@@ -0,0 +1,263 @@
// (C) Copyright David Abrahams 2001. 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.
//
// See http://www.boost.org for most recent version including documentation.
//
// Revision History
// 16 Feb 2001 Added a missing const. Made the tests run (somewhat) with
// plain MSVC again. (David Abrahams)
// 11 Feb 2001 #if 0'd out use of counting_iterator on non-numeric types in
// MSVC without STLport, so that the other tests may proceed
// (David Abrahams)
// 04 Feb 2001 Added use of iterator_tests.hpp (David Abrahams)
// 28 Jan 2001 Removed not_an_iterator detritus (David Abrahams)
// 24 Jan 2001 Initial revision (David Abrahams)
#include <boost/config.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable:4786) // identifier truncated in debug info
#endif
#include <boost/pending/iterator_tests.hpp>
#include <boost/counting_iterator.hpp>
#include <boost/detail/iterator.hpp>
#include <iostream>
#include <climits>
#include <iterator>
#include <stdlib.h>
#include <boost/utility.hpp>
#include <vector>
#include <list>
#include <cassert>
#ifndef BOOST_NO_LIMITS
# include <limits>
#endif
#ifndef BOOST_NO_SLIST
# include <slist>
#endif
template <class T> struct is_numeric
{
enum { value =
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
std::numeric_limits<T>::is_specialized
#else
// Causes warnings with GCC, but how else can I detect numeric types at
// compile-time?
(boost::is_convertible<int,T>::value &&
boost::is_convertible<T,int>::value)
#endif
};
};
// Special tests for RandomAccess CountingIterators.
template <class CountingIterator>
void category_test(
CountingIterator start,
CountingIterator finish,
std::random_access_iterator_tag)
{
typedef typename
boost::detail::iterator_traits<CountingIterator>::difference_type
difference_type;
difference_type distance = boost::detail::distance(start, finish);
// Pick a random position internal to the range
difference_type offset = (unsigned)rand() % distance;
assert(offset >= 0);
CountingIterator internal = start;
std::advance(internal, offset);
// Try some binary searches on the range to show that it's ordered
assert(std::binary_search(start, finish, *internal));
CountingIterator x,y;
boost::tie(x,y) = std::equal_range(start, finish, *internal);
assert(boost::detail::distance(x, y) == 1);
// Show that values outside the range can't be found
assert(!std::binary_search(start, boost::prior(finish), *finish));
// Do the generic random_access_iterator_test
typedef typename CountingIterator::value_type value_type;
std::vector<value_type> v;
for (value_type z = *start; z != *finish; ++z)
v.push_back(z);
if (v.size() >= 2)
{
// Note that this test requires a that the first argument is
// dereferenceable /and/ a valid iterator prior to the first argument
boost::random_access_iterator_test(start + 1, v.size() - 1, v.begin() + 1);
}
}
// Special tests for bidirectional CountingIterators
template <class CountingIterator>
void category_test(CountingIterator start, CountingIterator finish, std::bidirectional_iterator_tag)
{
if (finish != start
&& finish != boost::next(start)
&& finish != boost::next(boost::next(start)))
{
// Note that this test requires a that the first argument is
// dereferenceable /and/ a valid iterator prior to the first argument
boost::bidirectional_iterator_test(boost::next(start), boost::next(*start), boost::next(boost::next(*start)));
}
}
template <class CountingIterator>
void category_test(CountingIterator start, CountingIterator finish, std::forward_iterator_tag)
{
if (finish != start && finish != boost::next(start))
boost::forward_iterator_test(start, *start, boost::next(*start));
}
template <class CountingIterator>
void test_aux(CountingIterator start, CountingIterator finish)
{
typedef typename CountingIterator::iterator_category category;
typedef typename CountingIterator::value_type value_type;
// If it's a RandomAccessIterator we can do a few delicate tests
category_test(start, finish, category());
// Okay, brute force...
for (CountingIterator p = start; p != finish && boost::next(p) != finish; ++p)
{
assert(boost::next(*p) == *boost::next(p));
}
// prove that a reference can be formed to these values
typedef typename CountingIterator::value_type value;
const value* q = &*start;
(void)q; // suppress unused variable warning
}
template <class Incrementable>
void test(Incrementable start, Incrementable finish)
{
test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish));
}
template <class Integer>
void test_integer(Integer* = 0) // default arg works around MSVC bug
{
Integer start = 0;
Integer finish = 120;
test(start, finish);
}
template <class Container>
void test_container(Container* = 0) // default arg works around MSVC bug
{
Container c(1 + (unsigned)rand() % 1673);
const typename Container::iterator start = c.begin();
// back off by 1 to leave room for dereferenceable value at the end
typename Container::iterator finish = start;
std::advance(finish, c.size() - 1);
test(start, finish);
typedef typename Container::const_iterator const_iterator;
test(const_iterator(start), const_iterator(finish));
}
class my_int1 {
public:
my_int1() { }
my_int1(int x) : m_int(x) { }
my_int1& operator++() { ++m_int; return *this; }
bool operator==(const my_int1& x) const { return m_int == x.m_int; }
private:
int m_int;
};
namespace boost {
template <>
struct counting_iterator_traits<my_int1> {
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
};
}
class my_int2 {
public:
typedef void value_type;
typedef void pointer;
typedef void reference;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
my_int2() { }
my_int2(int x) : m_int(x) { }
my_int2& operator++() { ++m_int; return *this; }
my_int2& operator--() { --m_int; return *this; }
bool operator==(const my_int2& x) const { return m_int == x.m_int; }
private:
int m_int;
};
class my_int3 {
public:
typedef void value_type;
typedef void pointer;
typedef void reference;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
my_int3() { }
my_int3(int x) : m_int(x) { }
my_int3& operator++() { ++m_int; return *this; }
my_int3& operator+=(std::ptrdiff_t n) { m_int += n; return *this; }
std::ptrdiff_t operator-(const my_int3& x) const { return m_int - x.m_int; }
my_int3& operator--() { --m_int; return *this; }
bool operator==(const my_int3& x) const { return m_int == x.m_int; }
bool operator!=(const my_int3& x) const { return m_int != x.m_int; }
bool operator<(const my_int3& x) const { return m_int < x.m_int; }
private:
int m_int;
};
int main()
{
// Test the built-in integer types.
test_integer<char>();
test_integer<unsigned char>();
test_integer<signed char>();
test_integer<wchar_t>();
test_integer<short>();
test_integer<unsigned short>();
test_integer<int>();
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
test_integer<long long>();
test_integer<unsigned long long>();
#endif
// wrapping an iterator or non-built-in integer type causes an INTERNAL
// COMPILER ERROR in MSVC without STLport. I'm clueless as to why.
#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT)
// Test user-defined type.
test_integer<my_int1>();
test_integer<my_int2>();
test_integer<my_int3>();
// Some tests on container iterators, to prove we handle a few different categories
test_container<std::vector<int> >();
test_container<std::list<int> >();
# ifndef BOOST_NO_SLIST
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
# endif
// Also prove that we can handle raw pointers.
int array[2000];
test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));
#endif
std::cout << "test successful " << std::endl;
return 0;
}

41
fun_out_iter_example.cpp Normal file
View File

@@ -0,0 +1,41 @@
// (C) Copyright Jeremy Siek 2001. 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.
// Revision History:
// 27 Feb 2001 Jeremy Siek
// Initial checkin.
#include <iostream>
#include <string>
#include <vector>
#include <boost/function_output_iterator.hpp>
struct string_appender {
string_appender(std::string& s) : m_str(s) { }
void operator()(const std::string& x) const {
m_str += x;
}
std::string& m_str;
};
int main(int, char*[])
{
std::vector<std::string> x;
x.push_back("hello");
x.push_back(" ");
x.push_back("world");
x.push_back("!");
std::string s = "";
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout << s << std::endl;
return 0;
}

View File

@@ -0,0 +1,169 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Function Output Iterator Adaptor Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
"center" width="277" height="86">
<h1>Function Output Iterator Adaptor</h1>
Defined in header <a href=
"../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a>
<p>The function output iterator adaptor makes it easier to create
custom output iterators. The adaptor takes a <a
href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
Function</a> and creates a model of <a
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
Iterator</a>. Each item assigned to the output iterator is passed
as an argument to the unary function. The motivation for this
iterator is that creating a C++ Standard conforming output
iterator is non-trivial, particularly because the proper
implementation usually requires a proxy object. On the other hand,
creating a function (or function object) is much simpler.
<h2>Synopsis</h2>
<blockquote>
<pre>
namespace boost {
template &lt;class UnaryFunction&gt;
class function_output_iterator;
template &lt;class UnaryFunction&gt;
function_output_iterator&lt;UnaryFunction&gt;
make_function_output_iterator(const UnaryFunction&amp; f = UnaryFunction())
}
</pre>
</blockquote>
<h3>Example</h3>
In this example we create an output iterator that appends
each item onto the end of a string, using the <tt>string_appender</tt>
function.
<blockquote>
<pre>
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;boost/function_output_iterator.hpp&gt;
struct string_appender {
string_appender(std::string&amp; s) : m_str(s) { }
void operator()(const std::string&amp; x) const {
m_str += x;
}
std::string&amp; m_str;
};
int main(int, char*[])
{
std::vector&lt;std::string&gt; x;
x.push_back("hello");
x.push_back(" ");
x.push_back("world");
x.push_back("!");
std::string s = "";
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout &lt;&lt; s &lt;&lt; std::endl;
return 0;
}
</pre>
</blockquote>
<hr>
<h2><a name="function_output_iterator">The Function Output Iterator Class</a></h2>
<blockquote>
<pre>
template &lt;class UnaryFunction&gt;
class function_output_iterator;
</pre>
</blockquote>
The <tt>function_output_iterator</tt> class creates an <a
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
Iterator</a> out of a
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
Function</a>. Each item assigned to the output iterator is passed
as an argument to the unary function.
<h3>Template Parameters</h3>
<table border>
<tr>
<th>Parameter
<th>Description
<tr>
<td><tt>UnaryFunction</tt>
<td>The function type being wrapped. The return type of the
function is not used, so it can be <tt>void</tt>. The
function must be a model of <a
href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
Function</a>.</td>
</table>
<h3>Concept Model</h3>
The function output iterator class is a model of <a
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
Iterator</a>.
<h2>Members</h3>
The function output iterator implements the member functions
and operators required of the <a
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
Iterator</a> concept. In addition it has the following constructor:
<pre>
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
</pre>
<br>
<br>
<hr>
<h2><a name="make_function_output_iterator">The Function Output Iterator Object
Generator</a></h2>
The <tt>make_function_output_iterator()</tt> function provides a
more convenient way to create function output iterator objects. The
function saves the user the trouble of explicitly writing out the
iterator types. If the default argument is used, the function
type must be provided as an explicit template argument.
<blockquote>
<pre>
template &lt;class UnaryFunction&gt;
function_output_iterator&lt;UnaryFunction&gt;
make_function_output_iterator(const UnaryFunction&amp; f = UnaryFunction())
</pre>
</blockquote>
<hr>
<p>&copy; Copyright Jeremy Siek 2001. 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.
</body>
</html>

View File

@@ -0,0 +1,27 @@
// Test boost/pending/iterator_adaptors.hpp
// (C) Copyright Jeremy Siek 1999. 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.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 21 Jan 01 Initial version (Jeremy Siek)
#include <boost/config.hpp>
#include <list>
#include <boost/pending/iterator_adaptors.hpp>
int main()
{
typedef boost::iterator_adaptor<std::list<int>::iterator,
boost::default_iterator_policies,
int,int&,int*,std::bidirectional_iterator_tag> adaptor_type;
adaptor_type i;
i += 4;
return 0;
}

View File

@@ -0,0 +1,28 @@
// Test boost/pending/iterator_adaptors.hpp
// (C) Copyright Jeremy Siek 1999. 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.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 21 Jan 01 Initial version (Jeremy Siek)
#include <boost/config.hpp>
#include <iostream>
#include <iterator>
#include <boost/pending/iterator_adaptors.hpp>
int main()
{
typedef boost::iterator_adaptor<std::istream_iterator<int>,
boost::default_iterator_policies,
int,int&,int*,std::input_iterator_tag> adaptor_type;
adaptor_type iter;
--iter;
return 0;
}

View File

@@ -0,0 +1,96 @@
// (C) Copyright Jeremy Siek 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.
#include <boost/config.hpp>
#include <list>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
#include <boost/iterator_adaptors.hpp>
struct personnel_record {
personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
std::string m_name;
int m_ID;
};
struct select_name {
typedef personnel_record argument_type;
typedef std::string result_type;
const std::string& operator()(const personnel_record& r) const {
return r.m_name;
}
std::string& operator()(personnel_record& r) const {
return r.m_name;
}
};
struct select_ID {
typedef personnel_record argument_type;
typedef int result_type;
const int& operator()(const personnel_record& r) const {
return r.m_ID;
}
int& operator()(personnel_record& r) const {
return r.m_ID;
}
};
int main(int, char*[])
{
std::list<personnel_record> personnel_list;
personnel_list.push_back(personnel_record("Barney", 13423));
personnel_list.push_back(personnel_record("Fred", 12343));
personnel_list.push_back(personnel_record("Wilma", 62454));
personnel_list.push_back(personnel_record("Betty", 20490));
// Example of using projection_iterator_generator
// to print out the names in the personnel list.
boost::projection_iterator_generator<select_name,
std::list<personnel_record>::iterator>::type
personnel_first(personnel_list.begin()),
personnel_last(personnel_list.end());
std::copy(personnel_first, personnel_last,
std::ostream_iterator<std::string>(std::cout, "\n"));
std::cout << std::endl;
// Example of using projection_iterator_pair_generator
// to assign new ID numbers to the personnel.
typedef boost::projection_iterator_pair_generator<select_ID,
std::list<personnel_record>::iterator,
std::list<personnel_record>::const_iterator> PairGen;
PairGen::iterator ID_first(personnel_list.begin()),
ID_last(personnel_list.end());
int new_id = 0;
while (ID_first != ID_last) {
*ID_first = new_id++;
++ID_first;
}
PairGen::const_iterator const_ID_first(personnel_list.begin()),
const_ID_last(personnel_list.end());
std::copy(const_ID_first, const_ID_last,
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
// Example of using make_const_projection_iterator()
// to print out the names in the personnel list again.
std::copy
(boost::make_const_projection_iterator<select_name>(personnel_list.begin()),
boost::make_const_projection_iterator<select_name>(personnel_list.end()),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}

View File

@@ -0,0 +1,42 @@
// (C) Copyright Jeremy Siek 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.
#include <boost/config.hpp>
#include <iostream>
#include <algorithm>
#include <boost/iterator_adaptors.hpp>
int main(int, char*[])
{
char letters[] = "hello world!";
const int N = sizeof(letters)/sizeof(char) - 1;
std::cout << "original sequence of letters:\t"
<< letters << std::endl;
std::sort(letters, letters + N);
// Use reverse_iterator_generator to print a sequence
// of letters in reverse order.
boost::reverse_iterator_generator<char*>::type
reverse_letters_first(letters + N),
reverse_letters_last(letters);
std::cout << "letters in descending order:\t";
std::copy(reverse_letters_first, reverse_letters_last,
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
// Use make_reverse_iterator() to print the sequence
// of letters in reverse-reverse order.
std::cout << "letters in ascending order:\t";
std::copy(boost::make_reverse_iterator(reverse_letters_last),
boost::make_reverse_iterator(reverse_letters_first),
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
return 0;
}

View File

@@ -0,0 +1,44 @@
// (C) Copyright Jeremy Siek 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.
#include <functional>
#include <algorithm>
#include <iostream>
#include <boost/iterator_adaptors.hpp>
int
main(int, char*[])
{
// This is a simple example of using the transform_iterators class to
// generate iterators that multiply the value returned by dereferencing
// the iterator. In this case we are multiplying by 2.
// Would be cooler to use lambda library in this example.
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef std::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator_generator<Function, int*>::type doubling_iterator;
doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
i_end(x + N, std::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
std::cout << "adding 4 to each element in the array:" << std::endl;
std::copy(boost::make_transform_iterator(x, std::bind1st(std::plus<int>(), 4)),
boost::make_transform_iterator(x + N, std::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}

View File

@@ -1,659 +0,0 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & 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/type_traits.hpp>
/* Release notes:
20 Jan 2001:
Suppress an expected warning for MSVC
Added a test to prove that we can use void with is_same<>
Removed "press any key to exit" as it interferes with testing in large
batches.
(David Abahams)
31st July 2000:
Added extra tests for is_empty, is_convertible, alignment_of.
23rd July 2000:
Removed all call_traits tests to call_traits_test.cpp
Removed all compressed_pair tests to compressed_pair_tests.cpp
Improved tests macros
Tidied up specialistions of type_types classes for test cases.
*/
#include <iostream>
#include <typeinfo>
#include <boost/type_traits.hpp>
#include <boost/utility.hpp>
#include "type_traits_test.hpp"
using namespace boost;
// Since there is no compiler support, we should specialize:
// is_enum for all enumerations (is_enum implies is_POD)
// is_union for all unions
// is_empty for all empty composites
// is_POD for all PODs (except enums) (is_POD implies has_*)
// has_* for any UDT that has that trait and is not POD
enum enum_UDT{ one, two, three };
struct UDT
{
UDT();
~UDT();
UDT(const UDT&);
UDT& operator=(const UDT&);
int i;
void f1();
int f2();
int f3(int);
int f4(int, float);
};
struct POD_UDT { int x; };
struct empty_UDT{ ~empty_UDT(){}; };
struct empty_POD_UDT{};
union union_UDT
{
int x;
double y;
~union_UDT();
};
union POD_union_UDT
{
int x;
double y;
};
union empty_union_UDT
{
~empty_union_UDT();
};
union empty_POD_union_UDT{};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
namespace boost {
template <> struct is_enum<enum_UDT>
{ static const bool value = true; };
template <> struct is_POD<POD_UDT>
{ static const bool value = true; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_UDT>
{ static const bool value = true; };
template <> struct has_trivial_copy<empty_UDT>
{ static const bool value = true; };
template <> struct has_trivial_assign<empty_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_UDT>
{ static const bool value = true; };
template <> struct is_union<union_UDT>
{ static const bool value = true; };
template <> struct is_union<POD_union_UDT>
{ static const bool value = true; };
template <> struct is_POD<POD_union_UDT>
{ static const bool value = true; };
template <> struct is_union<empty_union_UDT>
{ static const bool value = true; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_union_UDT>
{ static const bool value = true; };
template <> struct has_trivial_copy<empty_union_UDT>
{ static const bool value = true; };
template <> struct has_trivial_assign<empty_union_UDT>
{ static const bool value = true; };
template <> struct is_union<empty_POD_union_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_union_UDT>
{ static const bool value = true; };
}
#else
namespace boost {
template <> struct is_enum<enum_UDT>
{ enum{ value = true }; };
template <> struct is_POD<POD_UDT>
{ enum{ value = true }; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_copy<empty_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_assign<empty_UDT>
{ enum{ value = true }; };
template <> struct is_POD<empty_POD_UDT>
{ enum{ value = true }; };
template <> struct is_union<union_UDT>
{ enum{ value = true }; };
template <> struct is_union<POD_union_UDT>
{ enum{ value = true }; };
template <> struct is_POD<POD_union_UDT>
{ enum{ value = true }; };
template <> struct is_union<empty_union_UDT>
{ enum{ value = true }; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_union_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_copy<empty_union_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_assign<empty_union_UDT>
{ enum{ value = true }; };
template <> struct is_union<empty_POD_union_UDT>
{ enum{ value = true }; };
template <> struct is_POD<empty_POD_union_UDT>
{ enum{ value = true }; };
}
#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(){};
};
//
// struct non_pointer:
// used to verify that is_pointer does not return
// true for class types that implement operator void*()
//
struct non_pointer
{
operator void*(){return this;}
};
//
// struct non_empty:
// used to verify that is_empty does not emit
// spurious warnings or errors.
//
struct non_empty : boost::noncopyable
{
int i;
};
// 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
// not considering cv-qual's as a part of the type -- they are considered
// compiler hints only. These failures should be fixed before long.
int main()
{
std::cout << "Checking type operations..." << std::endl << std::endl;
// cv-qualifiers applied to reference types should have no effect
// declare these here for later use with is_reference and remove_reference:
typedef int& r_type;
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable:4181) // qualifier applied to reference type ignored
#endif
typedef const r_type cr_type;
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
type_test(int, remove_reference<int>::type)
type_test(const int, remove_reference<const int>::type)
type_test(int, remove_reference<int&>::type)
type_test(const int, remove_reference<const int&>::type)
type_test(volatile int, remove_reference<volatile int&>::type)
type_test(int, remove_reference<cr_type>::type)
type_test(int, remove_const<const int>::type)
// Steve: fails on BCB4
type_test(volatile int, remove_const<volatile int>::type)
// Steve: fails on BCB4
type_test(volatile int, remove_const<const volatile int>::type)
type_test(int, remove_const<int>::type)
type_test(int*, remove_const<int* const>::type)
type_test(int, remove_volatile<volatile int>::type)
// Steve: fails on BCB4
type_test(const int, remove_volatile<const int>::type)
// Steve: fails on BCB4
type_test(const int, remove_volatile<const volatile int>::type)
type_test(int, remove_volatile<int>::type)
type_test(int*, remove_volatile<int* volatile>::type)
type_test(int, remove_cv<volatile int>::type)
type_test(int, remove_cv<const int>::type)
type_test(int, remove_cv<const volatile int>::type)
type_test(int, remove_cv<int>::type)
type_test(int*, remove_cv<int* volatile>::type)
type_test(int*, remove_cv<int* const>::type)
type_test(int*, remove_cv<int* const volatile>::type)
type_test(const int *, remove_cv<const int * const>::type)
type_test(int, remove_bounds<int>::type)
type_test(int*, remove_bounds<int*>::type)
type_test(int, remove_bounds<int[3]>::type)
type_test(int[3], remove_bounds<int[2][3]>::type)
std::cout << std::endl << "Checking type properties..." << std::endl << std::endl;
value_test(true, (is_same<void, void>::value))
value_test(false, (is_same<int, void>::value))
value_test(false, (is_same<void, int>::value))
value_test(true, (is_same<int, int>::value))
value_test(false, (is_same<int, const int>::value))
value_test(false, (is_same<int, int&>::value))
value_test(false, (is_same<int*, const int*>::value))
value_test(false, (is_same<int*, int*const>::value))
value_test(false, (is_same<int, int[2]>::value))
value_test(false, (is_same<int*, int[2]>::value))
value_test(false, (is_same<int[4], int[2]>::value))
value_test(false, is_const<int>::value)
value_test(true, is_const<const int>::value)
value_test(false, is_const<volatile int>::value)
value_test(true, is_const<const volatile int>::value)
value_test(false, is_volatile<int>::value)
value_test(false, is_volatile<const int>::value)
value_test(true, is_volatile<volatile int>::value)
value_test(true, is_volatile<const volatile int>::value)
value_test(true, is_void<void>::value)
// Steve: fails on BCB4
// JM: but looks as though it should according to [3.9.3p1]?
//value_test(false, is_void<const void>::value)
value_test(false, is_void<int>::value)
value_test(false, is_standard_unsigned_integral<UDT>::value)
value_test(false, is_standard_unsigned_integral<void>::value)
value_test(false, is_standard_unsigned_integral<bool>::value)
value_test(false, is_standard_unsigned_integral<char>::value)
value_test(false, is_standard_unsigned_integral<signed char>::value)
value_test(true, is_standard_unsigned_integral<unsigned char>::value)
value_test(false, is_standard_unsigned_integral<wchar_t>::value)
value_test(false, is_standard_unsigned_integral<short>::value)
value_test(true, is_standard_unsigned_integral<unsigned short>::value)
value_test(false, is_standard_unsigned_integral<int>::value)
value_test(true, is_standard_unsigned_integral<unsigned int>::value)
value_test(false, is_standard_unsigned_integral<long>::value)
value_test(true, is_standard_unsigned_integral<unsigned long>::value)
value_test(false, is_standard_unsigned_integral<float>::value)
value_test(false, is_standard_unsigned_integral<double>::value)
value_test(false, is_standard_unsigned_integral<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_unsigned_integral<long long>::value)
value_test(false, is_standard_unsigned_integral<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_unsigned_integral<__int64>::value)
value_test(false, is_standard_unsigned_integral<unsigned __int64>::value)
#endif
value_test(false, is_standard_signed_integral<UDT>::value)
value_test(false, is_standard_signed_integral<void>::value)
value_test(false, is_standard_signed_integral<bool>::value)
value_test(false, is_standard_signed_integral<char>::value)
value_test(true, is_standard_signed_integral<signed char>::value)
value_test(false, is_standard_signed_integral<unsigned char>::value)
value_test(false, is_standard_signed_integral<wchar_t>::value)
value_test(true, is_standard_signed_integral<short>::value)
value_test(false, is_standard_signed_integral<unsigned short>::value)
value_test(true, is_standard_signed_integral<int>::value)
value_test(false, is_standard_signed_integral<unsigned int>::value)
value_test(true, is_standard_signed_integral<long>::value)
value_test(false, is_standard_signed_integral<unsigned long>::value)
value_test(false, is_standard_signed_integral<float>::value)
value_test(false, is_standard_signed_integral<double>::value)
value_test(false, is_standard_signed_integral<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_signed_integral<long long>::value)
value_test(false, is_standard_signed_integral<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_signed_integral<__int64>::value)
value_test(false, is_standard_signed_integral<unsigned __int64>::value)
#endif
value_test(false, is_standard_arithmetic<UDT>::value)
value_test(false, is_standard_arithmetic<void>::value)
value_test(true, is_standard_arithmetic<bool>::value)
value_test(true, is_standard_arithmetic<char>::value)
value_test(true, is_standard_arithmetic<signed char>::value)
value_test(true, is_standard_arithmetic<unsigned char>::value)
value_test(true, is_standard_arithmetic<wchar_t>::value)
value_test(true, is_standard_arithmetic<short>::value)
value_test(true, is_standard_arithmetic<unsigned short>::value)
value_test(true, is_standard_arithmetic<int>::value)
value_test(true, is_standard_arithmetic<unsigned int>::value)
value_test(true, is_standard_arithmetic<long>::value)
value_test(true, is_standard_arithmetic<unsigned long>::value)
value_test(true, is_standard_arithmetic<float>::value)
value_test(true, is_standard_arithmetic<double>::value)
value_test(true, is_standard_arithmetic<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_arithmetic<long long>::value)
value_test(false, is_standard_arithmetic<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_arithmetic<__int64>::value)
value_test(false, is_standard_arithmetic<unsigned __int64>::value)
#endif
value_test(false, is_standard_fundamental<UDT>::value)
value_test(true, is_standard_fundamental<void>::value)
value_test(true, is_standard_fundamental<bool>::value)
value_test(true, is_standard_fundamental<char>::value)
value_test(true, is_standard_fundamental<signed char>::value)
value_test(true, is_standard_fundamental<unsigned char>::value)
value_test(true, is_standard_fundamental<wchar_t>::value)
value_test(true, is_standard_fundamental<short>::value)
value_test(true, is_standard_fundamental<unsigned short>::value)
value_test(true, is_standard_fundamental<int>::value)
value_test(true, is_standard_fundamental<unsigned int>::value)
value_test(true, is_standard_fundamental<long>::value)
value_test(true, is_standard_fundamental<unsigned long>::value)
value_test(true, is_standard_fundamental<float>::value)
value_test(true, is_standard_fundamental<double>::value)
value_test(true, is_standard_fundamental<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_fundamental<long long>::value)
value_test(false, is_standard_fundamental<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_fundamental<__int64>::value)
value_test(false, is_standard_fundamental<unsigned __int64>::value)
#endif
value_test(false, is_arithmetic<UDT>::value)
value_test(true, is_arithmetic<char>::value)
value_test(true, is_arithmetic<signed char>::value)
value_test(true, is_arithmetic<unsigned char>::value)
value_test(true, is_arithmetic<wchar_t>::value)
value_test(true, is_arithmetic<short>::value)
value_test(true, is_arithmetic<unsigned short>::value)
value_test(true, is_arithmetic<int>::value)
value_test(true, is_arithmetic<unsigned int>::value)
value_test(true, is_arithmetic<long>::value)
value_test(true, is_arithmetic<unsigned long>::value)
value_test(true, is_arithmetic<float>::value)
value_test(true, is_arithmetic<double>::value)
value_test(true, is_arithmetic<long double>::value)
value_test(true, is_arithmetic<bool>::value)
#ifdef ULLONG_MAX
value_test(true, is_arithmetic<long long>::value)
value_test(true, is_arithmetic<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(true, is_arithmetic<__int64>::value)
value_test(true, is_arithmetic<unsigned __int64>::value)
#endif
value_test(false, is_array<int>::value)
value_test(false, is_array<int*>::value)
value_test(false, is_array<const int*>::value)
value_test(false, is_array<const volatile int*>::value)
value_test(true, is_array<int[2]>::value)
value_test(true, is_array<const int[2]>::value)
value_test(true, is_array<const volatile int[2]>::value)
value_test(true, is_array<int[2][3]>::value)
value_test(true, is_array<UDT[2]>::value)
value_test(false, is_array<int(&)[2]>::value)
typedef void(*f1)();
typedef int(*f2)(int);
typedef int(*f3)(int, bool);
typedef void (UDT::*mf1)();
typedef int (UDT::*mf2)();
typedef int (UDT::*mf3)(int);
typedef int (UDT::*mf4)(int, float);
value_test(false, is_const<f1>::value)
value_test(false, is_reference<f1>::value)
value_test(false, is_array<f1>::value)
value_test(false, is_pointer<int>::value)
value_test(false, is_pointer<int&>::value)
value_test(true, is_pointer<int*>::value)
value_test(true, is_pointer<const int*>::value)
value_test(true, is_pointer<volatile int*>::value)
value_test(true, is_pointer<non_pointer*>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
value_test(false, is_pointer<int*const>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
value_test(false, is_pointer<int*volatile>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
value_test(false, is_pointer<int*const volatile>::value)
// JM 02 Oct 2000:
value_test(false, is_pointer<non_pointer>::value)
value_test(false, is_pointer<int*&>::value)
value_test(false, is_pointer<int(&)[2]>::value)
value_test(false, is_pointer<int[2]>::value)
value_test(false, is_pointer<char[sizeof(void*)]>::value)
value_test(true, is_pointer<f1>::value)
value_test(true, is_pointer<f2>::value)
value_test(true, is_pointer<f3>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf1>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf2>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf3>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf4>::value)
value_test(false, is_reference<bool>::value)
value_test(true, is_reference<int&>::value)
value_test(true, is_reference<const int&>::value)
value_test(true, is_reference<volatile int &>::value)
value_test(true, is_reference<r_type>::value)
value_test(true, is_reference<cr_type>::value)
value_test(true, is_reference<const UDT&>::value)
value_test(false, is_class<int>::value)
value_test(false, is_class<const int>::value)
value_test(false, is_class<volatile int>::value)
value_test(false, is_class<int*>::value)
value_test(false, is_class<int* const>::value)
value_test(false, is_class<int[2]>::value)
value_test(false, is_class<int&>::value)
value_test(false, is_class<mf4>::value)
value_test(false, is_class<f1>::value)
value_test(false, is_class<enum_UDT>::value)
value_test(true, is_class<UDT>::value)
value_test(true, is_class<UDT const>::value)
value_test(true, is_class<UDT volatile>::value)
value_test(true, is_class<empty_UDT>::value)
value_test(true, is_class<std::iostream>::value)
value_test(false, is_class<UDT*>::value)
value_test(false, is_class<UDT[2]>::value)
value_test(false, is_class<UDT&>::value)
value_test(true, is_object<int>::value)
value_test(true, is_object<UDT>::value)
value_test(false, is_object<int&>::value)
value_test(false, is_object<void>::value)
value_test(true, is_standard_scalar<int>::value)
value_test(true, is_extension_scalar<void*>::value)
value_test(false, is_enum<int>::value)
value_test(true, is_enum<enum_UDT>::value)
value_test(false, is_member_pointer<f1>::value)
value_test(false, is_member_pointer<f2>::value)
value_test(false, is_member_pointer<f3>::value)
value_test(true, is_member_pointer<mf1>::value)
value_test(true, is_member_pointer<mf2>::value)
value_test(true, is_member_pointer<mf3>::value)
value_test(true, is_member_pointer<mf4>::value)
value_test(false, is_empty<int>::value)
value_test(false, is_empty<int*>::value)
value_test(false, is_empty<int&>::value)
#if defined(__MWERKS__) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
// apparent compiler bug causes this to fail to compile:
value_fail(false, is_empty<int[2]>::value)
#else
value_test(false, is_empty<int[2]>::value)
#endif
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
value_fail(false, is_empty<f1>::value)
#else
value_test(false, is_empty<f1>::value)
#endif
value_test(false, is_empty<mf1>::value)
value_test(false, is_empty<UDT>::value)
value_test(true, is_empty<empty_UDT>::value)
value_test(true, is_empty<empty_POD_UDT>::value)
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
value_fail(true, is_empty<empty_union_UDT>::value)
#else
value_test(true, is_empty<empty_union_UDT>::value)
#endif
value_test(false, is_empty<enum_UDT>::value)
value_test(true, is_empty<boost::noncopyable>::value)
value_test(false, is_empty<non_empty>::value)
value_test(true, has_trivial_constructor<int>::value)
value_test(true, has_trivial_constructor<int*>::value)
value_test(true, has_trivial_constructor<int*const>::value)
value_test(true, has_trivial_constructor<const int>::value)
value_test(true, has_trivial_constructor<volatile int>::value)
value_test(true, has_trivial_constructor<int[2]>::value)
value_test(true, has_trivial_constructor<int[3][2]>::value)
value_test(true, has_trivial_constructor<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_constructor<f1>::value)
value_test(true, has_trivial_constructor<mf2>::value)
value_test(false, has_trivial_constructor<UDT>::value)
value_test(true, has_trivial_constructor<empty_UDT>::value)
value_test(true, has_trivial_constructor<enum_UDT>::value)
value_test(true, has_trivial_copy<int>::value)
value_test(true, has_trivial_copy<int*>::value)
value_test(true, has_trivial_copy<int*const>::value)
value_test(true, has_trivial_copy<const int>::value)
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
value_test(true, has_trivial_copy<volatile int>::value)
value_test(true, has_trivial_copy<int[2]>::value)
value_test(true, has_trivial_copy<int[3][2]>::value)
value_test(true, has_trivial_copy<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_copy<f1>::value)
value_test(true, has_trivial_copy<mf2>::value)
value_test(false, has_trivial_copy<UDT>::value)
value_test(true, has_trivial_copy<empty_UDT>::value)
value_test(true, has_trivial_copy<enum_UDT>::value)
value_test(true, has_trivial_assign<int>::value)
value_test(true, has_trivial_assign<int*>::value)
value_test(true, has_trivial_assign<int*const>::value)
value_test(true, has_trivial_assign<const int>::value)
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
value_test(true, has_trivial_assign<volatile int>::value)
value_test(true, has_trivial_assign<int[2]>::value)
value_test(true, has_trivial_assign<int[3][2]>::value)
value_test(true, has_trivial_assign<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_assign<f1>::value)
value_test(true, has_trivial_assign<mf2>::value)
value_test(false, has_trivial_assign<UDT>::value)
value_test(true, has_trivial_assign<empty_UDT>::value)
value_test(true, has_trivial_assign<enum_UDT>::value)
value_test(true, has_trivial_destructor<int>::value)
value_test(true, has_trivial_destructor<int*>::value)
value_test(true, has_trivial_destructor<int*const>::value)
value_test(true, has_trivial_destructor<const int>::value)
value_test(true, has_trivial_destructor<volatile int>::value)
value_test(true, has_trivial_destructor<int[2]>::value)
value_test(true, has_trivial_destructor<int[3][2]>::value)
value_test(true, has_trivial_destructor<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_destructor<f1>::value)
value_test(true, has_trivial_destructor<mf2>::value)
value_test(false, has_trivial_destructor<UDT>::value)
value_test(false, has_trivial_destructor<empty_UDT>::value)
value_test(true, has_trivial_destructor<enum_UDT>::value)
value_test(true, is_POD<int>::value)
value_test(true, is_POD<int*>::value)
// Steve: was 'true', should be 'false', via 3.9p10
value_test(false, is_POD<int&>::value)
value_test(true, is_POD<int*const>::value)
value_test(true, is_POD<const int>::value)
// Steve: was 'false', should be 'true', via 3.9p10
value_test(true, is_POD<volatile int>::value)
// Steve: was 'true', should be 'false', via 3.9p10
value_test(false, is_POD<const int&>::value)
value_test(true, is_POD<int[2]>::value)
value_test(true, is_POD<int[3][2]>::value)
value_test(true, is_POD<int[2][4][5][6][3]>::value)
value_test(true, is_POD<f1>::value)
value_test(true, is_POD<mf2>::value)
value_test(false, is_POD<UDT>::value)
value_test(false, is_POD<empty_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, int>::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(true, (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)";
return failures;
}