diff --git a/libcxx/include/functional b/libcxx/include/functional --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -2349,6 +2349,8 @@ struct __callable<_Fp, true> { static const bool value = is_same::value || + is_same::type, + _Rp>::value || is_convertible::type, _Rp>::value; }; diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// + +#include +#include + +#include "test_macros.h" + +struct NonCopyable { + NonCopyable() = default; + NonCopyable(NonCopyable&&) = delete; + friend bool operator==(NonCopyable, NonCopyable) { return true; } +}; + +struct LargeLambda { + int a[100]; + NonCopyable operator()() const { return NonCopyable(); } + NonCopyable operator()(int) const { return NonCopyable(); } +}; + +void test() +{ + std::function f1a = []() { return NonCopyable(); }; + std::function f2a = +[]() { return NonCopyable(); }; + std::function f3a = LargeLambda(); + std::function f4a = std::ref(f1a); + std::function f1b = [](int) { return NonCopyable(); }; + std::function f2b = +[](int) { return NonCopyable(); }; + std::function f3b = LargeLambda(); + std::function f4b = std::ref(f1b); + + assert(f1a() == f2a()); + assert(f3a() == f4a()); + assert(f1b(1) == f2b(1)); + assert(f3b(1) == f4b(1)); +} + +void ctad_test() +{ + std::function f1a = []() { return NonCopyable(); }; + std::function f2a = +[]() { return NonCopyable(); }; + std::function f1b = [](int) { return NonCopyable(); }; + std::function f2b = +[](int) { return NonCopyable(); }; + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); + static_assert(std::is_same_v>); +} + +int main(int, char**) +{ + test(); + ctad_test(); + return 0; +}