Skip to content

Commit 28f704d

Browse files
committed
[libc++] Implement P0288R9 (move_only_function)
1 parent 915e9ad commit 28f704d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2757
-50
lines changed

libcxx/docs/ABIGuarantees.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ This flag adds ``[[clang::trivial_abi]]`` to ``unique_ptr``, which makes it triv
157157
---------------------------------------------
158158
This flag adds ``[[clang::trivial_abi]]`` to ``shared_ptr``, which makes it trivial for the purpose of calls.
159159

160+
``_LIBCPP_ABI_MOVE_ONLY_FUNCTION_TRIVIAL_ABI``
161+
---------------------------------------------
162+
This flag adds ``[[clang::trivial_abi]]`` to ``move_only_function``, which makes it trivial for the purpose of calls.
163+
160164

161165
Types that public aliases reference
162166
===================================

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ Status
356356
---------------------------------------------------------- -----------------
357357
``__cpp_lib_modules`` ``202207L``
358358
---------------------------------------------------------- -----------------
359-
``__cpp_lib_move_only_function`` *unimplemented*
359+
``__cpp_lib_move_only_function`` ``202110L``
360360
---------------------------------------------------------- -----------------
361361
``__cpp_lib_optional`` ``202110L``
362362
---------------------------------------------------------- -----------------

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Implemented Papers
4949
- P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__)
5050
- P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://llvm.org/PR105424>`__)
5151
- P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
52+
- P0288R9 - ``move_only_function`` (`Github <https://llvm.org/PR105157>`__) This feature is currently experimental and
53+
thereofre requires ``-fexperimental-library``.
5254

5355
Improvements and New Features
5456
-----------------------------

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"`P2136R3 <https://wg21.link/P2136R3>`__","invoke_r","2021-06 (Virtual)","|Complete|","17","`#105155 <https://github.com/llvm/llvm-project/issues/105155>`__",""
2424
"`P2166R1 <https://wg21.link/P2166R1>`__","A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr","2021-06 (Virtual)","|Complete|","13","`#105156 <https://github.com/llvm/llvm-project/issues/105156>`__",""
2525
"","","","","","",""
26-
"`P0288R9 <https://wg21.link/P0288R9>`__","``any_invocable``","2021-10 (Virtual)","","","`#105157 <https://github.com/llvm/llvm-project/issues/105157>`__",""
26+
"`P0288R9 <https://wg21.link/P0288R9>`__","``move_only_function``","2021-10 (Virtual)","|Complete|","22","`#105157 <https://github.com/llvm/llvm-project/issues/105157>`__",""
2727
"`P0798R8 <https://wg21.link/P0798R8>`__","Monadic operations for ``std::optional``","2021-10 (Virtual)","|Complete|","14","`#105158 <https://github.com/llvm/llvm-project/issues/105158>`__",""
2828
"`P0849R8 <https://wg21.link/P0849R8>`__","``auto(x)``: ``DECAY_COPY`` in the language","2021-10 (Virtual)","|Complete|","14","`#105159 <https://github.com/llvm/llvm-project/issues/105159>`__",""
2929
"`P1072R10 <https://wg21.link/P1072R10>`__","``basic_string::resize_and_overwrite``","2021-10 (Virtual)","|Complete|","14","`#105160 <https://github.com/llvm/llvm-project/issues/105160>`__",""

libcxx/include/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,9 @@ set(files
430430
__functional/is_transparent.h
431431
__functional/mem_fn.h
432432
__functional/mem_fun_ref.h
433+
__functional/move_only_function.h
434+
__functional/move_only_function_common.h
435+
__functional/move_only_function_impl.h
433436
__functional/not_fn.h
434437
__functional/operations.h
435438
__functional/perfect_forward.h

libcxx/include/__configuration/abi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
8484
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
8585
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
86+
# define _LIBCPP_ABI_MOVE_ONLY_FUNCTION_TRIVIAL_ABI
8687

8788
#elif _LIBCPP_ABI_VERSION == 1
8889
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))

libcxx/include/__configuration/experimental.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@
3333
#define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
3434
#define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
3535
#define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
36+
#define _LIBCPP_HAS_EXPERIMENTAL_MOVE_ONLY_FUNCTION _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
3637

3738
#endif // _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_H
10+
#define _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_H
11+
12+
#include <__config>
13+
14+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15+
# pragma GCC system_header
16+
#endif
17+
18+
#if _LIBCPP_STD_VER >= 23 && _LIBCPP_HAS_EXPERIMENTAL_MOVE_ONLY_FUNCTION
19+
20+
// move_only_function design:
21+
//
22+
// move_only_function has a small buffer with a size of `3 * sizeof(void*)` bytes. This buffer can only be used when the
23+
// object to be stored is "trivially relocatable" (currently only when it is trivially move constructible and trivially
24+
// destructible). The vtable entry for the destructor is a null pointer when the stored object is trivially
25+
// destructible.
26+
//
27+
// trivially relocatable: It would also be possible to store nothrow_move_constructible types, but that would mean
28+
// that move_only_function itself would not be trivially relocatable anymore. The decision to keep move_only_function
29+
// trivially relocatable was made because we expect move_only_function to be stored persistently most of the time, since
30+
// std::function_ref can be used for cases where a function object doesn't need to be stored.
31+
//
32+
// buffer size: We did a survey of six implementations from various vendors. Three of them had a buffer size of 24 bytes
33+
// on 64 bit systems. This will also allow storing a function object containing a std::string or std::vector inside the
34+
// small buffer once there is a language definition of "trivially relocatable".
35+
//
36+
// interaction with copyable_function: When converting a copyable_function into a move_only_function we want to avoid
37+
// wrapping the copyable_function inside the move_only_function to avoid a double indirection. Instead, we copy the
38+
// small buffer and use copyable_function's vtable.
39+
40+
// NOLINTBEGIN(readability-duplicate-include)
41+
# define _LIBCPP_IN_MOVE_ONLY_FUNCTION_H
42+
43+
# include <__functional/move_only_function_impl.h>
44+
45+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
46+
# include <__functional/move_only_function_impl.h>
47+
48+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
49+
# include <__functional/move_only_function_impl.h>
50+
51+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
52+
# include <__functional/move_only_function_impl.h>
53+
54+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
55+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
56+
# include <__functional/move_only_function_impl.h>
57+
58+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
59+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
60+
# include <__functional/move_only_function_impl.h>
61+
62+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
63+
# include <__functional/move_only_function_impl.h>
64+
65+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
66+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
67+
# include <__functional/move_only_function_impl.h>
68+
69+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
70+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
71+
# include <__functional/move_only_function_impl.h>
72+
73+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
74+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
75+
# include <__functional/move_only_function_impl.h>
76+
77+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
78+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
79+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
80+
# include <__functional/move_only_function_impl.h>
81+
82+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
83+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
84+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
85+
# include <__functional/move_only_function_impl.h>
86+
87+
# undef _LIBCPP_IN_MOVE_ONLY_FUNCTION_H
88+
// NOLINTEND(readability-duplicate-include)
89+
90+
#endif // _LIBCPP_STD_VER >= 23 && _LIBCPP_HAS_EXPERIMENTAL_MOVE_ONLY_FUNCTION
91+
92+
#endif // _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_H
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H
10+
#define _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H
11+
12+
#include <__config>
13+
14+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15+
# pragma GCC system_header
16+
#endif
17+
18+
#if _LIBCPP_STD_VER >= 23 && _LIBCPP_HAS_EXPERIMENTAL_MOVE_ONLY_FUNCTION
19+
20+
_LIBCPP_BEGIN_NAMESPACE_STD
21+
22+
template <class...>
23+
class move_only_function;
24+
25+
template <class>
26+
inline constexpr bool __is_move_only_function_v = false;
27+
28+
template <class... _Args>
29+
inline constexpr bool __is_move_only_function_v<move_only_function<_Args...>> = true;
30+
31+
template <class _BufferT, class _ReturnT, class... _ArgTypes>
32+
struct _MoveOnlyFunctionVTable {
33+
using _CallFunc _LIBCPP_NODEBUG = _ReturnT(_BufferT&, _ArgTypes...);
34+
using _DestroyFunc _LIBCPP_NODEBUG = void(_BufferT&) noexcept;
35+
36+
_CallFunc* __call_;
37+
_DestroyFunc* __destroy_;
38+
};
39+
40+
_LIBCPP_END_NAMESPACE_STD
41+
42+
#endif // _LIBCPP_STD_VER >= 23 && _LIBCPP_HAS_EXPERIMENTAL_MOVE_ONLY_FUNCTION
43+
44+
#endif // _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H

0 commit comments

Comments
 (0)