diff --git a/call_traits_test.cpp b/call_traits_test.cpp index 430ce4d..255b916 100644 --- a/call_traits_test.cpp +++ b/call_traits_test.cpp @@ -6,6 +6,8 @@ // warranty, and with no claim as to its suitability for any purpose. // standalone test program for +// 03 Oct 2000: +// Enabled extra tests for VC6. #include #include diff --git a/compressed_pair_test.cpp b/compressed_pair_test.cpp index ba6d81d..5c01da6 100644 --- a/compressed_pair_test.cpp +++ b/compressed_pair_test.cpp @@ -6,6 +6,8 @@ // warranty, and with no claim as to its suitability for any purpose. // standalone test program for +// Revised 03 Oct 2000: +// Enabled tests for VC6. #include #include @@ -39,7 +41,6 @@ template <> struct is_POD #endif } - int main() { compressed_pair cp1(1, 1.3); @@ -61,7 +62,7 @@ int main() assert(cp3.first() ==1); compressed_pair cp4; compressed_pair cp5; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#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); assert(cp6.first() == i); @@ -124,4 +125,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 994c974..25c9669 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: + 03 Oct 2000: + Added VC6 support (JM). 23rd July 2000: Additional comments added. (JM) Jan 2000: @@ -29,6 +31,315 @@ namespace boost { +#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) +// +// use member templates to emulate +// partial specialisation: +// +namespace detail{ + +template +class compressed_pair_0 +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + 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() {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_0& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +template +class compressed_pair_1 : T2 +{ +private: + T1 _first; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + 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) {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_1& y) + { + // no need to swap empty base class: + using std::swap; + swap(_first, y._first); + } +}; + +template +class compressed_pair_2 : T1 +{ +private: + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + 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() {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_2& y) + { + // no need to swap empty base class: + using std::swap; + swap(_second, y._second); + } +}; + +template +class compressed_pair_3 : T1, T2 +{ +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + 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() {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_3& y) + { + // no need to swap empty base classes: + } +}; + +// T1 == T2, and empty +template +class compressed_pair_4 : T1 +{ +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_4() : T1() {} + compressed_pair_4(first_param_type x, second_param_type) : T1(x) {} + explicit compressed_pair_4(first_param_type x) : T1(x) {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_4& y) + { + // no need to swap empty base classes: + } +}; + +// T1 == T2, not empty +template +class compressed_pair_5 +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_5() : _first(), _second() {} + compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {} + explicit compressed_pair_5(first_param_type x) : _first(x), _second() {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_5& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +template +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_0 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_1 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_2 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_3 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_4 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_5 type; + }; +}; + +template +struct compressed_pair_traits +{ +private: + typedef compressed_pair_chooser::value, is_empty::value, is_same::value> chooser; + typedef typename chooser::template rebind bound_type; +public: + typedef typename bound_type::type type; +}; + +} // namespace detail + +template +class compressed_pair : public detail::compressed_pair_traits::type +{ +private: + typedef typename detail::compressed_pair_traits::type base_type; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + 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) {} + + first_reference first() { return base_type::first(); } + first_const_reference first() const { return base_type::first(); } + + second_reference second() { return base_type::second(); } + second_const_reference second() const { return base_type::second(); } +}; + +template +inline void swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +#else +// no partial specialisation, no member templates: template class compressed_pair @@ -72,6 +383,8 @@ inline void swap(compressed_pair& x, compressed_pair& y) x.swap(y); } +#endif + } // boost #endif // BOOST_OB_COMPRESSED_PAIR_HPP diff --git a/type_traits_test.cpp b/type_traits_test.cpp index 2a48ecf..1b80838 100644 --- a/type_traits_test.cpp +++ b/type_traits_test.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "type_traits_test.hpp" using namespace boost; @@ -162,6 +163,24 @@ 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 @@ -169,7 +188,6 @@ struct VD : VB // 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; @@ -221,6 +239,8 @@ int main() value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) + value_test(false, (is_same::value)) + value_test(false, (is_same::value)) value_test(false, is_const::value) value_test(true, is_const::value) @@ -379,12 +399,21 @@ int main() 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) // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1 value_test(false, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1 value_test(false, is_pointer::value) + // JM 02 Oct 2000: + value_test(false, is_pointer::value) + value_test(true, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) @@ -444,19 +473,29 @@ int main() value_test(false, is_empty::value) value_test(false, is_empty::value) value_test(false, is_empty::value) -#ifdef __MWERKS__ +#if defined(__MWERKS__) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // apparent compiler bug causes this to fail to compile: value_fail(false, is_empty::value) #else value_test(false, is_empty::value) #endif +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + value_fail(false, is_empty::value) +#else value_test(false, is_empty::value) +#endif value_test(false, is_empty::value) value_test(false, is_empty::value) value_test(true, is_empty::value) value_test(true, is_empty::value) +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + value_fail(true, is_empty::value) +#else value_test(true, is_empty::value) +#endif value_test(false, is_empty::value) + value_test(true, is_empty::value) + value_test(false, is_empty::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) @@ -541,7 +580,7 @@ int main() value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); - //value_test(false, (boost::is_convertible::value)); + value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) value_test(false, (boost::is_convertible::value));