From c0c9748c113b5cc4beff4fa0223a3b4feba8ce46 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 21 Feb 2013 18:16:55 +0000 Subject: [PATCH] Constrain bind operator()() to not exist if the call is not valid. Fixes http://llvm.org/bugs/show_bug.cgi?id=15295. llvm-svn: 175774 --- libcxx/include/functional | 48 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/libcxx/include/functional b/libcxx/include/functional index 3bee1ed..2582782 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1624,16 +1624,38 @@ struct __mu_return : public ____mu_return<_Ti, __is_reference_wrapper<_Ti>::value, is_bind_expression<_Ti>::value, - 0 < is_placeholder<_Ti>::value, + 0 < is_placeholder<_Ti>::value && + is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, _TupleUj> { }; template +struct _is_valid_bind_return +{ + static const bool value = false; +}; + +template +struct _is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; +}; + +template +struct _is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return::type...>::value; +}; + +template ::value> struct __bind_return; template -struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> +struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> { typedef typename __invoke_of < @@ -1647,7 +1669,7 @@ struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> }; template -struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> +struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> { typedef typename __invoke_of < @@ -1673,8 +1695,10 @@ template class __bind : public __weak_result_type::type> { +protected: typedef typename decay<_Fp>::type _Fd; typedef tuple::type...> _Td; +private: _Fd __f_; _Td __bound_args_; @@ -1731,7 +1755,7 @@ public: template _LIBCPP_INLINE_VISIBILITY - typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type + typename __bind_return >::type operator()(_Args&& ...__args) const { return __apply_functor(__f_, __bound_args_, __indices(), @@ -1747,6 +1771,8 @@ class __bind_r : public __bind<_Fp, _BoundArgs...> { typedef __bind<_Fp, _BoundArgs...> base; + typedef typename base::_Fd _Fd; + typedef typename base::_Td _Td; public: typedef _Rp result_type; @@ -1784,7 +1810,12 @@ public: template _LIBCPP_INLINE_VISIBILITY - result_type + typename enable_if + < + is_convertible >::type, + result_type>::value, + result_type + >::type operator()(_Args&& ...__args) { return base::operator()(_VSTD::forward<_Args>(__args)...); @@ -1792,7 +1823,12 @@ public: template _LIBCPP_INLINE_VISIBILITY - result_type + typename enable_if + < + is_convertible >::type, + result_type>::value, + result_type + >::type operator()(_Args&& ...__args) const { return base::operator()(_VSTD::forward<_Args>(__args)...); -- 2.7.4