more VC6 type-traits and compressed pair fixes

[SVN r7921]
This commit is contained in:
John Maddock
2000-10-07 10:53:47 +00:00
parent 28594a22f1
commit 6161ce15c7
3 changed files with 109 additions and 16 deletions

View File

@@ -41,6 +41,24 @@ template <> struct is_POD<empty_POD_UDT>
#endif
}
struct non_empty1
{
int i;
non_empty1() : i(1){}
non_empty1(int v) : i(v){}
friend bool operator==(const non_empty1& a, const non_empty1& b)
{ return a.i == b.i; }
};
struct non_empty2
{
int i;
non_empty2() : i(3){}
non_empty2(int v) : i(v){}
friend bool operator==(const non_empty2& a, const non_empty2& b)
{ return a.i == b.i; }
};
int main()
{
compressed_pair<int, double> cp1(1, 1.3);
@@ -54,14 +72,21 @@ int main()
assert(cp1b.second() == 1.3);
assert(cp1.first() == 2);
assert(cp1.second() == 2.3);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
compressed_pair<non_empty1, non_empty2> cp1c(non_empty1(9));
assert(cp1c.second() == non_empty2());
assert(cp1c.first() == non_empty1(9));
compressed_pair<non_empty1, non_empty2> cp1d(non_empty2(9));
assert(cp1d.second() == non_empty2(9));
assert(cp1d.first() == non_empty1());
compressed_pair<empty_UDT, int> cp2(2);
assert(cp2.second() == 2);
#endif
compressed_pair<int, empty_UDT> cp3(1);
assert(cp3.first() ==1);
compressed_pair<empty_UDT, empty_UDT> cp4;
compressed_pair<empty_UDT, empty_POD_UDT> cp5;
compressed_pair<int, empty_UDT> cp9(empty_UDT());
compressed_pair<int, empty_UDT> cp10(1);
assert(cp10.first() == 1);
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
int i = 0;
compressed_pair<int&, int&> cp6(i,i);
@@ -124,4 +149,3 @@ template compressed_pair<double, int[2]>::compressed_pair();

View File

@@ -8,6 +8,8 @@
// see libs/utility/compressed_pair.hpp
//
/* Release notes:
07 Oct 2000:
Added better single argument constructor support.
03 Oct 2000:
Added VC6 support (JM).
23rd July 2000:
@@ -34,10 +36,51 @@ namespace boost
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
//
// use member templates to emulate
// partial specialisation:
// partial specialisation. Note that due to
// problems with overload resolution with VC6
// each of the compressed_pair versions that follow
// have one template single-argument constructor
// in place of two specific constructors:
//
namespace detail{
template <class A, class T1, class T2>
struct best_convertion_traits
{
typedef char one;
typedef char (&two)[2];
static A a;
static one test(T1);
static two test(T2);
enum { value = sizeof(test(a)) };
};
template <int>
struct init_one;
template <>
struct init_one<1>
{
template <class A, class T1, class T2>
static void init(const A& a, T1* p1, T2*)
{
*p1 = a;
}
};
template <>
struct init_one<2>
{
template <class A, class T1, class T2>
static void init(const A& a, T1*, T2* p2)
{
*p2 = a;
}
};
// T1 != T2, both non-empty
template <class T1, class T2>
class compressed_pair_0
{
@@ -56,7 +99,11 @@ public:
compressed_pair_0() : _first(), _second() {}
compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
explicit compressed_pair_0(first_param_type x) : _first(x), _second() {}
template <class A>
explicit compressed_pair_0(const A& val)
{
init_one<best_convertion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
@@ -72,6 +119,7 @@ public:
}
};
// T1 != T2, T2 empty
template <class T1, class T2>
class compressed_pair_1 : T2
{
@@ -89,7 +137,11 @@ public:
compressed_pair_1() : T2(), _first() {}
compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
explicit compressed_pair_1(first_param_type x) : T2(), _first(x) {}
template <class A>
explicit compressed_pair_1(const A& val)
{
init_one<best_convertion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
@@ -105,6 +157,7 @@ public:
}
};
// T1 != T2, T1 empty
template <class T1, class T2>
class compressed_pair_2 : T1
{
@@ -122,7 +175,11 @@ public:
compressed_pair_2() : T1(), _second() {}
compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
explicit compressed_pair_2(first_param_type x) : T1(x), _second() {}
template <class A>
explicit compressed_pair_2(const A& val)
{
init_one<best_convertion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
}
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
@@ -138,6 +195,7 @@ public:
}
};
// T1 != T2, both empty
template <class T1, class T2>
class compressed_pair_3 : T1, T2
{
@@ -153,7 +211,11 @@ public:
compressed_pair_3() : T1(), T2() {}
compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
explicit compressed_pair_3(first_param_type x) : T1(x), T2() {}
template <class A>
explicit compressed_pair_3(const A& val)
{
init_one<best_convertion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
}
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
@@ -183,6 +245,7 @@ public:
compressed_pair_4() : T1() {}
compressed_pair_4(first_param_type x, second_param_type) : T1(x) {}
// only one single argument constructor since T1 == T2
explicit compressed_pair_4(first_param_type x) : T1(x) {}
first_reference first() { return *this; }
@@ -216,6 +279,7 @@ public:
compressed_pair_5() : _first(), _second() {}
compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
// only one single argument constructor since T1 == T2
explicit compressed_pair_5(first_param_type x) : _first(x), _second() {}
first_reference first() { return _first; }
@@ -321,9 +385,8 @@ public:
compressed_pair() : base_type() {}
compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
explicit compressed_pair(first_param_type x) : base_type(x) {}
// can't define this in case T1 == T2:
// explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
template <class A>
explicit compressed_pair(const A& x) : base_type(x){}
first_reference first() { return base_type::first(); }
first_const_reference first() const { return base_type::first(); }
@@ -389,3 +452,4 @@ inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
#endif // BOOST_OB_COMPRESSED_PAIR_HPP

View File

@@ -182,7 +182,6 @@ 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
@@ -384,7 +383,11 @@ int main()
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)
@@ -396,15 +399,15 @@ int main()
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<f1>::value)
value_test(true, is_pointer<f2>::value)
value_test(true, is_pointer<f3>::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)
@@ -416,6 +419,8 @@ int main()
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)