Thanks Doug. Ultimately I'd like to see is_convertible mapped into a compiler intrinsic.
-Howard On Jan 24, 2011, at 8:15 PM, Douglas Gregor wrote: > Author: dgregor > Date: Mon Jan 24 19:15:41 2011 > New Revision: 124166 > > URL: http://llvm.org/viewvc/llvm-project?rev=124166&view=rev > Log: > Eliminate the C++0x-only is_convertible testing function that accepts > a cv-qualifier rvalue reference to the type, e.g., > > template <class _Tp> char __test(const volatile typename > remove_reference<_Tp>::type&&); > > The use of this function signature rather than the more > straightforward one used in C++98/03 mode, e.g., > > template <class _Tp> char __test(_Tp); > > is broken in two ways: > > 1) An rvalue reference cannot bind to lvalues, so is_convertible<X&, > X&>::value would be false. This breaks two of the unique_ptr tests > on Clang and GCC >= 4.5. Prior GCC's seem to have allowed rvalue > references to bind to lvalues, allowing this bug to slip in. > > 2) By adding cv-qualifiers to the type we're converting to, we get > some incorrect "true" results for, e.g., is_convertible<const X&, X&>::value. > > > > > Modified: > libcxx/trunk/include/type_traits > libcxx/trunk/test/utilities/meta/meta.rel/is_convertible.pass.cpp > > Modified: libcxx/trunk/include/type_traits > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=124166&r1=124165&r2=124166&view=diff > ============================================================================== > --- libcxx/trunk/include/type_traits (original) > +++ libcxx/trunk/include/type_traits Mon Jan 24 19:15:41 2011 > @@ -600,11 +600,7 @@ > > namespace __is_convertible_imp > { > -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES > -template <class _Tp> char __test(const volatile typename > remove_reference<_Tp>::type&&); > -#else > template <class _Tp> char __test(_Tp); > -#endif > template <class _Tp> __two __test(...); > #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES > template <class _Tp> _Tp&& __source(); > > Modified: libcxx/trunk/test/utilities/meta/meta.rel/is_convertible.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/meta/meta.rel/is_convertible.pass.cpp?rev=124166&r1=124165&r2=124166&view=diff > ============================================================================== > --- libcxx/trunk/test/utilities/meta/meta.rel/is_convertible.pass.cpp > (original) > +++ libcxx/trunk/test/utilities/meta/meta.rel/is_convertible.pass.cpp Mon Jan > 24 19:15:41 2011 > @@ -16,6 +16,10 @@ > typedef void Function(); > typedef char Array[1]; > > +class NonCopyable { > + NonCopyable(NonCopyable&); > +}; > + > int main() > { > { > @@ -366,4 +370,15 @@ > static_assert((!std::is_convertible<const char*, char*>::value), ""); > static_assert(( std::is_convertible<const char*, const char*>::value), > ""); > } > + { > + static_assert((std::is_convertible<NonCopyable&, NonCopyable&>::value), > ""); > + static_assert((std::is_convertible<NonCopyable&, const > NonCopyable&>::value), ""); > + static_assert((std::is_convertible<NonCopyable&, const volatile > NonCopyable&>::value), ""); > + static_assert((std::is_convertible<NonCopyable&, volatile > NonCopyable&>::value), ""); > + static_assert((std::is_convertible<const NonCopyable&, const > NonCopyable&>::value), ""); > + static_assert((std::is_convertible<const NonCopyable&, const volatile > NonCopyable&>::value), ""); > + static_assert((std::is_convertible<volatile NonCopyable&, const volatile > NonCopyable&>::value), ""); > + static_assert((std::is_convertible<const volatile NonCopyable&, const > volatile NonCopyable&>::value), ""); > + static_assert((!std::is_convertible<const NonCopyable&, > NonCopyable&>::value), ""); > + } > } > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
