diff --git a/compressed_pair_test.cpp b/compressed_pair_test.cpp index 5c01da6..dd49373 100644 --- a/compressed_pair_test.cpp +++ b/compressed_pair_test.cpp @@ -41,6 +41,24 @@ template <> struct is_POD #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 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 cp1c(non_empty1(9)); + assert(cp1c.second() == non_empty2()); + assert(cp1c.first() == non_empty1(9)); + compressed_pair cp1d(non_empty2(9)); + assert(cp1d.second() == non_empty2(9)); + assert(cp1d.first() == non_empty1()); compressed_pair cp2(2); assert(cp2.second() == 2); -#endif compressed_pair cp3(1); assert(cp3.first() ==1); compressed_pair cp4; compressed_pair cp5; + compressed_pair cp9(empty_UDT()); + compressed_pair 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 cp6(i,i); @@ -124,4 +149,3 @@ template compressed_pair::compressed_pair(); - diff --git a/include/boost/detail/ob_compressed_pair.hpp b/include/boost/detail/ob_compressed_pair.hpp index 25c9669..d562722 100644 --- a/include/boost/detail/ob_compressed_pair.hpp +++ b/include/boost/detail/ob_compressed_pair.hpp @@ -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 +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 +struct init_one; + +template <> +struct init_one<1> +{ + template + static void init(const A& a, T1* p1, T2*) + { + *p1 = a; + } +}; + +template <> +struct init_one<2> +{ + template + static void init(const A& a, T1*, T2* p2) + { + *p2 = a; + } +}; + + +// T1 != T2, both non-empty template 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 + explicit compressed_pair_0(const A& val) + { + init_one::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 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 + explicit compressed_pair_1(const A& val) + { + init_one::value>::init(val, &_first, static_cast(this)); + } first_reference first() { return _first; } first_const_reference first() const { return _first; } @@ -105,6 +157,7 @@ public: } }; +// T1 != T2, T1 empty template 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 + explicit compressed_pair_2(const A& val) + { + init_one::value>::init(val, static_cast(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 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 + explicit compressed_pair_3(const A& val) + { + init_one::value>::init(val, static_cast(this), static_cast(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 + 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& x, compressed_pair& y) #endif // BOOST_OB_COMPRESSED_PAIR_HPP + diff --git a/type_traits_test.cpp b/type_traits_test.cpp index 5ab8c3f..09471bc 100644 --- a/type_traits_test.cpp +++ b/type_traits_test.cpp @@ -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::value) value_test(false, is_array::value) + value_test(false, is_array::value) + value_test(false, is_array::value) value_test(true, is_array::value) + value_test(true, is_array::value) + value_test(true, is_array::value) value_test(true, is_array::value) value_test(true, is_array::value) value_test(false, is_array::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::value) + value_test(false, is_reference::value) + value_test(false, is_array::value) value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) - value_test(true, is_pointer::value) - value_test(true, is_pointer::value) - value_test(true, is_pointer::value) value_test(true, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1 value_test(false, is_pointer::value) @@ -416,6 +419,8 @@ int main() value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(false, is_pointer::value) + value_test(false, is_pointer::value) + value_test(false, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value)