mirror of
https://github.com/boostorg/utility.git
synced 2025-08-01 22:04:31 +02:00
more VC6 type-traits and compressed pair fixes
[SVN r7921]
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
@@ -397,14 +400,14 @@ int main()
|
||||
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)
|
||||
|
Reference in New Issue
Block a user