[libcxx-commits] [PATCH] D94452: [libc++] Support immovable return types in std::function.
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jan 11 14:28:14 PST 2021
Quuxplusone created this revision.
Quuxplusone added reviewers: ldionne, logan-5.
Quuxplusone added a project: libc++.
Quuxplusone requested review of this revision.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.
Bug(?) reported by @logan-5.
This is either "oh yeah, sure, trivial, ship it" or "geez this is a really deep open question about the meaning of the standardese" — I'm not sure which. I've posted in #standardese but not otherwise tried to start a discussion/issue yet.
https://eel.is/c++draft/func.wrap.func#general-2
https://eel.is/c++draft/func.require#2
The crux seems to be what [func.require] means by "<expression> implicitly converted to R" — if the type of <expression> is already R, then "implicit conversion to R" is a no-op? Anyway, `is_convertible` seems to be the wrong tool for that job.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D94452
Files:
libcxx/include/functional
libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp
Index: libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp
===================================================================
--- /dev/null
+++ 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
+
+// <functional>
+
+#include <functional>
+#include <cassert>
+
+#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<NonCopyable()> f1a = []() { return NonCopyable(); };
+ std::function<NonCopyable()> f2a = +[]() { return NonCopyable(); };
+ std::function<NonCopyable()> f3a = LargeLambda();
+ std::function<NonCopyable()> f4a = std::ref(f1a);
+ std::function<NonCopyable(int)> f1b = [](int) { return NonCopyable(); };
+ std::function<NonCopyable(int)> f2b = +[](int) { return NonCopyable(); };
+ std::function<NonCopyable(int)> f3b = LargeLambda();
+ std::function<NonCopyable(int)> 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<decltype(f1a), std::function<NonCopyable()>>);
+ static_assert(std::is_same_v<decltype(f2a), std::function<NonCopyable()>>);
+ static_assert(std::is_same_v<decltype(f1b), std::function<NonCopyable(int)>>);
+ static_assert(std::is_same_v<decltype(f2b), std::function<NonCopyable(int)>>);
+}
+
+int main(int, char**)
+{
+ test();
+ ctad_test();
+ return 0;
+}
Index: libcxx/include/functional
===================================================================
--- libcxx/include/functional
+++ libcxx/include/functional
@@ -2349,6 +2349,8 @@
struct __callable<_Fp, true>
{
static const bool value = is_same<void, _Rp>::value ||
+ is_same<typename __invoke_of<_Fp, _ArgTypes...>::type,
+ _Rp>::value ||
is_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
_Rp>::value;
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94452.315926.patch
Type: text/x-patch
Size: 3057 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210111/5b9d1fae/attachment.bin>
More information about the libcxx-commits
mailing list