Fixes for various compilers from John Maddock

[SVN r7629]
This commit is contained in:
Beman Dawes 2000-07-24 17:59:52 +00:00
parent 06adfe9658
commit a005f03cc2
5 changed files with 418 additions and 284 deletions

View File

@ -24,6 +24,13 @@
*
*/
/* Release notes:
23rd July 2000:
Added explicit failure for broken compilers that don't support these examples.
Fixed broken gcc support (broken using directive).
Reordered tests slightly.
*/
#include <iostream>
#include <typeinfo>
#include <algorithm>
@ -39,6 +46,10 @@ using std::cout;
using std::endl;
using std::cin;
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#error "Sorry, without template partial specialisation support there isn't anything to test here..."
#endif
namespace opt{
//
@ -221,6 +232,10 @@ struct swapper
}
};
#ifdef __GNUC__
using std::swap;
#endif
template <>
struct swapper<true>
{
@ -295,6 +310,44 @@ int main()
result = t.elapsed();
cout << "destroy_array<int>(unoptimised#2): " << result << endl << endl;
cout << "testing fill(char)...\n"
"[Some standard library versions may already perform this optimisation.]" << endl;
/*cache load*/ opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
}
result = t.elapsed();
cout << "opt::fill<char*, char>: " << result << endl;
/*cache load*/ std::fill(c_array, c_array + array_size, (char)3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::fill(c_array, c_array + array_size, (char)3);
}
result = t.elapsed();
cout << "std::fill<char*, char>: " << result << endl << endl;
cout << "testing fill(int)...\n"
"[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl;
/*cache load*/ opt::fill<int*, int>(i_array, i_array + array_size, 3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::fill<int*, int>(i_array, i_array + array_size, 3);
}
result = t.elapsed();
cout << "opt::fill<int*, int>: " << result << endl;
/*cache load*/ std::fill(i_array, i_array + array_size, 3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::fill(i_array, i_array + array_size, 3);
}
result = t.elapsed();
cout << "std::fill<int*, int>: " << result << endl << endl;
cout << "testing copy...\n"
"[Some standard library versions may already perform this optimisation.]" << endl;
/*cache load*/ opt::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
@ -347,43 +400,6 @@ int main()
result = t.elapsed();
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
cout << "testing fill(char)...\n"
"[Some standard library versions may already perform this optimisation.]" << endl;
/*cache load*/ opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
}
result = t.elapsed();
cout << "opt::fill<char*, char>: " << result << endl;
/*cache load*/ std::fill(c_array, c_array + array_size, (char)3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::fill(c_array, c_array + array_size, (char)3);
}
result = t.elapsed();
cout << "std::fill<char*, char>: " << result << endl << endl;
cout << "testing fill(int)...\n"
"[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl;
/*cache load*/ opt::fill<int*, int>(i_array, i_array + array_size, 3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::fill<int*, int>(i_array, i_array + array_size, 3);
}
result = t.elapsed();
cout << "opt::fill<int*, int>: " << result << endl;
/*cache load*/ std::fill(i_array, i_array + array_size, 3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::fill(i_array, i_array + array_size, 3);
}
result = t.elapsed();
cout << "std::fill<int*, int>: " << result << endl << endl;
//
// testing iter_swap
@ -404,3 +420,4 @@ int main()

View File

@ -6,6 +6,12 @@
#include <typeinfo>
#include <boost/call_traits.hpp>
#ifdef __BORLANDC__
// 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)
// arrays are contained by value, and have to be treated as a special case:
@ -28,7 +34,7 @@ struct contained
contained() {}
contained(param_type p) : v_(p){}
// return byval:
result_type value() { return v_; }
result_type value()const { return v_; }
// return by_ref:
reference get() { return v_; }
const_reference const_get()const { return v_; }
@ -37,6 +43,7 @@ struct contained
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, std::size_t N>
struct contained<T[N]>
{
@ -53,19 +60,23 @@ struct contained<T[N]>
std::copy(p, p+N, v_);
}
// return byval:
result_type value() { return v_; }
result_type value()const { return v_; }
// return by_ref:
reference get() { return v_; }
const_reference const_get()const { return v_; }
void call(param_type p){}
};
#endif
template <class T>
contained<typename boost::call_traits<T>::value_type> wrap(const T& t)
{
return contained<typename boost::call_traits<T>::value_type>(t);
typedef typename boost::call_traits<T>::value_type ct;
return contained<ct>(t);
}
namespace test{
template <class T1, class T2>
std::pair<
typename boost::call_traits<T1>::value_type,
@ -77,6 +88,8 @@ std::pair<
typename boost::call_traits<T2>::value_type>(t1, t2);
}
} // namespace test
using namespace std;
//
@ -108,51 +121,40 @@ void checker<T>::operator()(param_type p)
cout << endl;
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, std::size_t N>
struct checker<T[N]>
{
typedef typename boost::call_traits<T[N]>::param_type param_type;
void operator()(param_type);
void operator()(param_type t)
{
contained<T[N]> c(t);
cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
unsigned int i = 0;
for(i = 0; i < N; ++i)
assert(t[i] == c.value()[i]);
for(i = 0; i < N; ++i)
assert(t[i] == c.get()[i]);
for(i = 0; i < N; ++i)
assert(t[i] == c.const_get()[i]);
cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl;
cout << endl;
}
};
template <class T, std::size_t N>
void checker<T[N]>::operator()(param_type t)
{
contained<T[N]> c(t);
cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
unsigned int i = 0;
for(i = 0; i < N; ++i)
assert(t[i] == c.value()[i]);
for(i = 0; i < N; ++i)
assert(t[i] == c.get()[i]);
for(i = 0; i < N; ++i)
assert(t[i] == c.const_get()[i]);
cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl;
cout << endl;
}
#endif
//
// check_wrap:
// verifies behaviour of "wrap":
//
template <class T, class U, class V>
void check_wrap(T c, U u, const V& v)
template <class T, class U>
void check_wrap(const contained<T>& w, const U& u)
{
cout << "checking contained<" << typeid(T::value_type).name() << ">..." << endl;
assert(c.get() == u);
cout << "typeof deduced argument was: " << typeid(V).name() << endl;
cout << "typeof deduced parameter after adjustment was: " << typeid(v).name() << endl;
cout << "typeof contained<" << typeid(T::value_type).name() << ">::v_ is: " << typeid(&T::v_).name() << endl;
cout << "typeof contained<" << typeid(T::value_type).name() << ">::value is: " << typeid(&T::value).name() << endl;
cout << "typeof contained<" << typeid(T::value_type).name() << ">::get is: " << typeid(&T::get).name() << endl;
cout << "typeof contained<" << typeid(T::value_type).name() << ">::const_get is: " << typeid(&T::const_get).name() << endl;
cout << "typeof contained<" << typeid(T::value_type).name() << ">::call is: " << typeid(&T::call).name() << endl;
cout << endl;
cout << "checking contained<" << typeid(T).name() << ">..." << endl;
assert(w.value() == u);
}
//
@ -176,6 +178,29 @@ struct UDT
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()
{
@ -188,6 +213,7 @@ int main()
int* pi = &i;
checker<int*> c3;
c3(pi);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
checker<int&> c4;
c4(i);
checker<const int&> c5;
@ -196,13 +222,147 @@ int main()
int a[2] = {1,2};
checker<int[2]> c6;
c6(a);
#endif
check_wrap(wrap(2), 2, 2);
check_wrap(wrap(2), 2);
const char ca[4] = "abc";
// compiler can't deduce this for some reason:
//check_wrap(wrap(ca), ca, ca);
check_wrap(wrap(a), a, a);
check_make_pair(::make_pair(a, a), a, a);
//check_wrap(wrap(ca), ca);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
check_wrap(wrap(a), a);
check_make_pair(test::make_pair(a, a), a, a);
#endif
return 0;
// 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;
typedef const r_type cr_type;
type_test(UDT, boost::call_traits<UDT>::value_type)
type_test(UDT&, boost::call_traits<UDT>::reference)
type_test(const UDT&, boost::call_traits<UDT>::const_reference)
type_test(const UDT&, boost::call_traits<UDT>::param_type)
type_test(int, boost::call_traits<int>::value_type)
type_test(int&, boost::call_traits<int>::reference)
type_test(const int&, boost::call_traits<int>::const_reference)
type_test(const int, boost::call_traits<int>::param_type)
type_test(int*, boost::call_traits<int*>::value_type)
type_test(int*&, boost::call_traits<int*>::reference)
type_test(int*const&, boost::call_traits<int*>::const_reference)
type_test(int*const, boost::call_traits<int*>::param_type)
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
type_test(int&, boost::call_traits<int&>::value_type)
type_test(int&, boost::call_traits<int&>::reference)
type_test(const int&, boost::call_traits<int&>::const_reference)
type_test(int&, boost::call_traits<int&>::param_type)
#if !(defined(__GNUC__) && (__GNUC__ < 3))
type_test(int&, boost::call_traits<cr_type>::value_type)
type_test(int&, boost::call_traits<cr_type>::reference)
type_test(const int&, boost::call_traits<cr_type>::const_reference)
type_test(int&, boost::call_traits<cr_type>::param_type)
#else
std::cout << "GNU C++ cannot instantiate call_traits<cr_type>, skipping four tests (4 errors)" << std::endl;
failures += 4;
test_count += 4;
#endif
type_test(const int&, boost::call_traits<const int&>::value_type)
type_test(const int&, boost::call_traits<const int&>::reference)
type_test(const int&, boost::call_traits<const int&>::const_reference)
type_test(const int&, boost::call_traits<const int&>::param_type)
type_test(const int*, boost::call_traits<int[3]>::value_type)
type_test(int(&)[3], boost::call_traits<int[3]>::reference)
type_test(const int(&)[3], boost::call_traits<int[3]>::const_reference)
type_test(const int*const, boost::call_traits<int[3]>::param_type)
type_test(const int*, boost::call_traits<const int[3]>::value_type)
type_test(const int(&)[3], boost::call_traits<const int[3]>::reference)
type_test(const int(&)[3], boost::call_traits<const int[3]>::const_reference)
type_test(const int*const, boost::call_traits<const int[3]>::param_type)
#else
std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl;
failures += 20;
test_count += 20;
#endif
std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit";
std::cin.get();
return failures;
}
//
// define call_traits tests to check that the assertions in the docs do actually work
// this is an instantiate only set of tests:
//
template <typename T, bool isarray = false>
struct call_traits_test
{
static void assert_construct(boost::call_traits<T>::param_type val);
};
template <typename T, bool isarray>
void call_traits_test<T, isarray>::assert_construct(boost::call_traits<T>::param_type val)
{
//
// this is to check that the call_traits assertions are valid:
T t(val);
boost::call_traits<T>::value_type v(t);
boost::call_traits<T>::reference r(t);
boost::call_traits<T>::const_reference cr(t);
boost::call_traits<T>::param_type p(t);
boost::call_traits<T>::value_type v2(v);
boost::call_traits<T>::value_type v3(r);
boost::call_traits<T>::value_type v4(p);
boost::call_traits<T>::reference r2(v);
boost::call_traits<T>::reference r3(r);
boost::call_traits<T>::const_reference cr2(v);
boost::call_traits<T>::const_reference cr3(r);
boost::call_traits<T>::const_reference cr4(cr);
boost::call_traits<T>::const_reference cr5(p);
boost::call_traits<T>::param_type p2(v);
boost::call_traits<T>::param_type p3(r);
boost::call_traits<T>::param_type p4(p);
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <typename T>
struct call_traits_test<T, true>
{
static void assert_construct(boost::call_traits<T>::param_type val);
};
template <typename T>
void call_traits_test<T, true>::assert_construct(boost::call_traits<T>::param_type val)
{
//
// this is to check that the call_traits assertions are valid:
T t;
boost::call_traits<T>::value_type v(t);
boost::call_traits<T>::value_type v5(val);
boost::call_traits<T>::reference r = t;
boost::call_traits<T>::const_reference cr = t;
boost::call_traits<T>::reference r2 = r;
#ifndef __BORLANDC__
// C++ Builder buglet:
boost::call_traits<T>::const_reference cr2 = r;
#endif
boost::call_traits<T>::param_type p(t);
boost::call_traits<T>::value_type v2(v);
boost::call_traits<T>::const_reference cr3 = cr;
boost::call_traits<T>::value_type v3(r);
boost::call_traits<T>::value_type v4(p);
boost::call_traits<T>::param_type p2(v);
boost::call_traits<T>::param_type p3(r);
boost::call_traits<T>::param_type p4(p);
}
#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
// now check call_traits assertions by instantiating call_traits_test:
template struct call_traits_test<int>;
template struct call_traits_test<const int>;
template struct call_traits_test<int*>;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template struct call_traits_test<int&>;
template struct call_traits_test<const int&>;
template struct call_traits_test<int[2], true>;
#endif

View File

@ -6,6 +6,13 @@
// See http://www.boost.org for most recent version including documentation.
/* Release notes:
23rd July 2000:
Fixed array specialization. (JM)
Added Borland specific fixes for reference types
(issue raised by Steve Cleary).
*/
#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
#define BOOST_DETAIL_CALL_TRAITS_HPP
@ -66,6 +73,37 @@ struct call_traits<T&>
typedef T& param_type; // hh removed const
};
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x550)
// these are illegal specialisations; cv-qualifies applied to
// references have no effect according to [8.3.2p1],
// C++ Builder requires them though as it treats cv-qualified
// references as distinct types...
template <typename T>
struct call_traits<T&const>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
template <typename T>
struct call_traits<T&volatile>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
template <typename T>
struct call_traits<T&const volatile>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
#endif
template <typename T, std::size_t N>
struct call_traits<T [N]>
{
@ -76,7 +114,7 @@ public:
typedef const T* value_type;
typedef array_type& reference;
typedef const array_type& const_reference;
typedef const T* param_type;
typedef const T* const param_type;
};
template <typename T, std::size_t N>
@ -89,7 +127,7 @@ public:
typedef const T* value_type;
typedef array_type& reference;
typedef const array_type& const_reference;
typedef const T* param_type;
typedef const T* const param_type;
};
}

View File

@ -6,7 +6,14 @@
// See http://www.boost.org for most recent version including documentation.
//
// this version crippled for use with crippled compilers - John Maddock Jan 2000.
/* Release notes:
23rd July 2000:
Additional comments added. (JM)
Jan 2000:
Original version: this version crippled for use with crippled compilers
- John Maddock Jan 2000.
*/
#ifndef BOOST_OB_COMPRESSED_PAIR_HPP
#define BOOST_OB_COMPRESSED_PAIR_HPP
@ -41,7 +48,8 @@ public:
compressed_pair() : _first(), _second() {}
compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
explicit compressed_pair(first_param_type x) : _first(x), _second() {}
//explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
// can't define this in case T1 == T2:
// explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }

View File

@ -4,12 +4,18 @@
// 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.
/* Release notes:
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/compressed_pair.hpp>
#include <boost/call_traits.hpp>
using namespace boost;
@ -20,73 +26,25 @@ using namespace boost;
//
// define tests here
unsigned failures = 0;
unsigned test_count = 0;
#define value_test(v, x) if(v == x) /*std::cout << "checking value of " << #x << "...OK" << std::endl*/;\
else{++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
#define type_test(v, x) if(is_same<v, x>::value) /*std::cout << "checking type of " << #x << "...OK" << std::endl*/;\
else{++failures; std::cout << "checking type of " << #x << "...failed (type was: " << typeid(is_same<v, x>).name() << ")" << std::endl;}
template <typename T, bool isarray = false>
struct call_traits_test
{
static void assert_construct(call_traits<T>::param_type val);
};
template <typename T, bool isarray>
void call_traits_test<T, isarray>::assert_construct(call_traits<T>::param_type val)
{
//
// this is to check that the call_traits assertions are valid:
T t(val);
call_traits<T>::value_type v(t);
call_traits<T>::reference r(t);
call_traits<T>::const_reference cr(t);
call_traits<T>::param_type p(t);
call_traits<T>::value_type v2(v);
call_traits<T>::value_type v3(r);
call_traits<T>::value_type v4(p);
call_traits<T>::reference r2(v);
call_traits<T>::reference r3(r);
call_traits<T>::const_reference cr2(v);
call_traits<T>::const_reference cr3(r);
call_traits<T>::const_reference cr4(cr);
call_traits<T>::const_reference cr5(p);
call_traits<T>::param_type p2(v);
call_traits<T>::param_type p3(r);
call_traits<T>::param_type p4(p);
}
#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
template <typename T>
struct call_traits_test<T, true>
{
static void assert_construct(call_traits<T>::param_type val);
};
template <typename T>
void call_traits_test<T, true>::assert_construct(call_traits<T>::param_type val)
{
//
// this is to check that the call_traits assertions are valid:
T t;
call_traits<T>::value_type v(t);
call_traits<T>::reference r(t);
call_traits<T>::const_reference cr(t);
call_traits<T>::param_type p(t);
call_traits<T>::value_type v2(v);
call_traits<T>::value_type v3(r);
call_traits<T>::value_type v4(p);
call_traits<T>::reference r2(v);
call_traits<T>::reference r3(r);
call_traits<T>::const_reference cr2(v);
call_traits<T>::const_reference cr3(r);
call_traits<T>::const_reference cr4(cr);
call_traits<T>::const_reference cr5(p);
call_traits<T>::param_type p2(v);
call_traits<T>::param_type p3(r);
call_traits<T>::param_type p4(p);
}
#endif //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:
// is_enum for all enumerations (is_enum implies is_POD)
@ -96,12 +54,6 @@ void call_traits_test<T, true>::assert_construct(call_traits<T>::param_type val)
// has_* for any UDT that has that trait and is not POD
enum enum_UDT{ one, two, three };
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
template <> struct is_enum<enum_UDT>
{ static const bool value = true; };
}
#endif
struct UDT
{
UDT();
@ -116,74 +68,47 @@ struct UDT
int f4(int, float);
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
struct POD_UDT { int x; };
namespace boost {
template <> struct is_POD<POD_UDT>
{ static const bool value = true; };
}
#endif
struct empty_UDT
{
~empty_UDT(){};
};
namespace boost {
//template <> struct is_empty<empty_UDT>
//{ static const bool value = true; };
// this type is not POD, so we have to specialize the has_* individually
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
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; };
}
#endif
struct empty_UDT{ ~empty_UDT(){}; };
struct empty_POD_UDT{};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
template <> struct is_empty<empty_POD_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_UDT>
{ static const bool value = true; };
}
#endif
union union_UDT
{
int x;
double y;
~union_UDT();
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
template <> struct is_union<union_UDT>
{ static const bool value = true; };
}
#endif
union POD_union_UDT
{
int x;
double y;
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
template <> struct is_union<POD_union_UDT>
{ static const bool value = true; };
template <> struct is_POD<POD_union_UDT>
{ static const bool value = true; };
}
#endif
union empty_union_UDT
{
~empty_union_UDT();
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
union empty_POD_union_UDT{};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
namespace boost {
template <> struct is_union<empty_union_UDT>
template <> struct is_enum<enum_UDT>
{ static const bool value = true; };
template <> struct is_empty<empty_union_UDT>
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>
@ -192,19 +117,48 @@ 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; };
}
#endif
union empty_POD_union_UDT{};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
template <> struct is_union<empty_POD_union_UDT>
{ static const bool value = true; };
template <> struct is_empty<empty_POD_union_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_union_UDT>
{ static const bool value = true; };
#endif
}
#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
// 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
@ -214,11 +168,18 @@ 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;
typedef const r_type cr_type;
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)
@ -246,14 +207,15 @@ int main()
type_test(int, remove_bounds<int[3]>::type)
type_test(int[3], remove_bounds<int[2][3]>::type)
type_test(const int, call_traits<int>::param_type)
type_test(const char, call_traits<char>::param_type)
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
type_test(char&, call_traits<char&>::param_type)
type_test(const char&, call_traits<const char&>::param_type)
#endif
std::cout << std::endl << "Checking type properties..." << std::endl << std::endl;
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_const<int>::value)
value_test(true, is_const<const int>::value)
value_test(false, is_const<volatile int>::value)
@ -266,7 +228,8 @@ int main()
value_test(true, is_void<void>::value)
// Steve: fails on BCB4
value_test(false, is_void<const void>::value)
// 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)
@ -432,6 +395,8 @@ int main()
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(false, is_class<int>::value)
value_test(false, is_class<const int>::value)
@ -477,8 +442,9 @@ int main()
value_test(false, is_empty<f1>::value)
value_test(false, is_empty<mf1>::value)
value_test(false, is_empty<UDT>::value)
value_test(false, is_empty<std::iostream>::value)
value_test(true, is_empty<empty_UDT>::value)
value_test(true, is_empty<empty_POD_UDT>::value)
value_test(true, is_empty<empty_union_UDT>::value)
value_test(false, is_empty<enum_UDT>::value)
value_test(true, has_trivial_constructor<int>::value)
@ -558,66 +524,11 @@ int main()
value_test(false, is_POD<empty_UDT>::value)
value_test(true, is_POD<enum_UDT>::value)
compressed_pair<int, double> cp1;
compressed_pair<int, double> cp1b;
swap(cp1, cp1b);
compressed_pair<empty_UDT, int> cp2;
compressed_pair<int, empty_UDT> cp3;
compressed_pair<empty_UDT, empty_UDT> cp4;
compressed_pair<empty_UDT, empty_POD_UDT> cp5;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
int i;
compressed_pair<int&, int&> cp6(i,i);
compressed_pair<int, double[2]> cp7;
cp7.first();
double* pd = cp7.second();
#endif
value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
std::cout << std::endl << "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();
return 0;
return failures;
}
//
// instanciate some compressed pairs:
template class boost::compressed_pair<int, double>;
template class boost::compressed_pair<int, int>;
template class boost::compressed_pair<empty_UDT, int>;
template class boost::compressed_pair<int, empty_UDT>;
template class boost::compressed_pair<empty_UDT, empty_UDT>;
template class boost::compressed_pair<empty_UDT, empty_POD_UDT>;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
// now some for which only a few specific members can be instantiated,
// first references:
template double& compressed_pair<double, int&>::first();
template int& compressed_pair<double, int&>::second();
template compressed_pair<double, int&>::compressed_pair(int&);
template compressed_pair<double, int&>::compressed_pair(call_traits<double>::param_type,int&);
//
// and then arrays:
#ifndef __BORLANDC__
template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second();
#endif
template call_traits<double>::reference compressed_pair<double, int[2]>::first();
template compressed_pair<double, int[2]>::compressed_pair(const double&);
template compressed_pair<double, int[2]>::compressed_pair();
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
// now check call_traits assertions by instantiating call_traits_test:
template struct call_traits_test<int>;
template struct call_traits_test<const int>;
template struct call_traits_test<int*>;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template struct call_traits_test<int&>;
template struct call_traits_test<const int&>;
// this doesn't work (yet) (JM):
template struct call_traits_test<int[2], true>;
#endif