[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jun 7 05:00:45 PDT 2024
================
@@ -0,0 +1,233 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// This header is unguarded on purpose. This header is an implementation detail of move_only_function.h
+// and generates multiple versions of std::move_only_function
+
+#include <__config>
+#include <__functional/invoke.h>
+#include <__functional/move_only_function_common.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__utility/exchange.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/pointer_int_pair.h>
+#include <__utility/small_buffer.h>
+#include <__utility/swap.h>
+#include <cstddef>
+#include <cstring>
+#include <initializer_list>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP_IN_MOVE_ONLY_FUNCTION_H
+# error This header should only be included from move_only_function.h
+#endif
+
+#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_CV
+# define _LIBCPP_MOVE_ONLY_FUNCTION_CV
+#endif
+
+#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_REF
----------------
EricWF wrote:
Huh, so I stand corrected here.
Normally, the way the terrible diagnostics come about is through the diagnostic caret pointing at a macro expansion. For example, were an invalid expression formed via a macro expansion, it would produce a diagnostic like:
https://godbolt.org/z/dKr1nzPd9
```
<source>:12:1: error: no matching function for call to 'invoke'
12 | EXPAND
```
However, since we never actually expand any of the expressions fully from a macro, and none of the macros lead an expression (where the caret might point, `_VSTD` was notorious for this), the diagnostics produced by your implementation don't get all muddy.
Neither do they really appear to hide too much information. I was worried it would be hard to tell the actual CV, ref, and noexcept qualifiers were present from a particular diagnostic. And while you can't see what's used from the source, the clang diagnostics always seem to provide enough information to figure out which specialization your in. But that also seems to work:
```
/home/eric/llvm-project/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.move/call/rvalue_const_noexcept.pass.cpp:51:5: error: no matching function for call to object of type 'std::move_only_function<void () const && noexcept>'
51 | f();
| ^
/home/eric/llvm-project/libcxx/include/__functional/move_only_function_impl.h:200:34: note: candidate function not viable: expects an rvalue for object argument
200 | _LIBCPP_HIDE_FROM_ABI _ReturnT operator()(_ArgTypes... __args) _LIBCPP_MOVE_ONLY_FUNCTION_CVREF
```
Now I still hate using the preprocessor, and dislike creating non-modular re-includable headers. And I have a strong aversion to its use. But diagnostics don't appear to be an issue here.
https://github.com/llvm/llvm-project/pull/94670
More information about the llvm-branch-commits
mailing list