Author: ericwf Date: Mon Jul 11 14:57:13 2016 New Revision: 275094 URL: http://llvm.org/viewvc/llvm-project?rev=275094&view=rev Log: Allow is_swappable to SFINAE on deleted/ambiguous swap functions
Modified: libcxx/trunk/include/type_traits libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp Modified: libcxx/trunk/include/type_traits URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=275094&r1=275093&r2=275094&view=diff ============================================================================== --- libcxx/trunk/include/type_traits (original) +++ libcxx/trunk/include/type_traits Mon Jul 11 14:57:13 2016 @@ -4446,15 +4446,20 @@ iter_swap(_ForwardIterator1 __a, _Forwar namespace __detail { // ALL generic swap overloads MUST already have a declaration available at this point. -using _VSTD::swap; -__nat swap(__any, __any); template <class _Tp, class _Up = _Tp, bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value> struct __swappable_with { - typedef decltype(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>())) __swap1; - typedef decltype(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>())) __swap2; + template <class _LHS, class _RHS> + static decltype(swap(_VSTD::declval<_LHS>(), _VSTD::declval<_RHS>())) + __test_swap(int); + template <class, class> + static __nat __test_swap(long); + + // Extra parens are needed for the C++03 definition of decltype. + typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; + typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; static const bool value = !is_same<__swap1, __nat>::value && !is_same<__swap2, __nat>::value; Modified: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp?rev=275094&r1=275093&r2=275094&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp Mon Jul 11 14:57:13 2016 @@ -49,8 +49,21 @@ struct M { void swap(M&&, M&&) {} +struct DeletedSwap { + friend void swap(DeletedSwap&, DeletedSwap&) = delete; +}; + } // namespace MyNS +namespace MyNS2 { + +struct AmbiguousSwap {}; + +template <class T> +void swap(T&, T&) {} + +} // end namespace MyNS2 + int main() { using namespace MyNS; @@ -70,6 +83,14 @@ int main() static_assert(!std::is_swappable<int() &>::value, ""); } { + // test that a deleted swap is correctly handled. + static_assert(!std::is_swappable<DeletedSwap>::value, ""); + } + { + // test that a swap with ambiguous overloads is handled correctly. + static_assert(!std::is_swappable<MyNS2::AmbiguousSwap>::value, ""); + } + { // test for presence of is_swappable_v static_assert(std::is_swappable_v<int>, ""); static_assert(!std::is_swappable_v<M>, ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits