From c05e98660f673191b13ae2fee8f6b823e515d4a2 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sun, 30 Jun 2013 19:48:15 +0000 Subject: [PATCH] Fix bind by making _is_valid_bind_return more robust. It should return false instead of give a compile time error, always. The problem was down in ____mu_return, the version that handles nested bind objects. This fixes http://llvm.org/bugs/show_bug.cgi?id=16343 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@185289 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/functional | 14 ++++- .../func.bind/func.bind.bind/nested.pass.cpp | 51 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp diff --git a/include/functional b/include/functional index 995db564c..d9e6ee94b 100644 --- a/include/functional +++ b/include/functional @@ -1594,12 +1594,24 @@ template struct ____mu_return; +template +struct ____mu_return_invokable // false +{ + typedef __nat type; +}; + template -struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> > +struct ____mu_return_invokable { typedef typename __invoke_of<_Ti&, _Uj...>::type type; }; +template +struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> > + : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> +{ +}; + template struct ____mu_return<_Ti, false, false, true, _TupleUj> { diff --git a/test/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp b/test/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp new file mode 100644 index 000000000..12720f7b5 --- /dev/null +++ b/test/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// unspecified bind(Fn, Types...); +// template +// unspecified bind(Fn, Types...); + +// http://llvm.org/bugs/show_bug.cgi?id=16343 + +#include +#include +#include + +struct power +{ + template + T + operator()(T a, T b) + { + return std::pow(a, b); + } +}; + +struct plus_one +{ + template + T + operator()(T a) + { + return a + 1; + } +}; + +int +main() +{ + using std::placeholders::_1; + + auto g = std::bind(power(), 2, _1); + assert(g(5) == 32); + assert(std::bind(plus_one(), g)(5) == 33); +}