Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cb723b8

Browse filesBrowse files
committed
[libc++] Implement P0288R9 (move_only_function)
1 parent 5780820 commit cb723b8
Copy full SHA for cb723b8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

45 files changed

+3475
-49
lines changed

‎libcxx/docs/FeatureTestMacroTable.rst

Copy file name to clipboardExpand all lines: libcxx/docs/FeatureTestMacroTable.rst
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ Status
348348
---------------------------------------------------------- -----------------
349349
``__cpp_lib_modules`` ``202207L``
350350
---------------------------------------------------------- -----------------
351-
``__cpp_lib_move_only_function`` *unimplemented*
351+
``__cpp_lib_move_only_function`` ``202110L``
352352
---------------------------------------------------------- -----------------
353353
``__cpp_lib_optional`` ``202110L``
354354
---------------------------------------------------------- -----------------
@@ -498,4 +498,3 @@ Status
498498
---------------------------------------------------------- -----------------
499499
``__cpp_lib_variant`` ``202306L``
500500
========================================================== =================
501-

‎libcxx/docs/ReleaseNotes/20.rst

Copy file name to clipboardExpand all lines: libcxx/docs/ReleaseNotes/20.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Implemented Papers
4545
- ``std::jthread`` and ``<stop_token>`` are not guarded behind ``-fexperimental-library`` anymore
4646
- P2674R1: A trait for implicit lifetime types (`Github <https://github.com/llvm/llvm-project/issues/105259>`__)
4747
- P0429R9: A Standard ``flat_map`` is partially implemented and ``flat_map`` is provided (`Github <https://github.com/llvm/llvm-project/issues/105190>`__)
48+
- P0288R9 - ``move_only_function``
4849

4950
Improvements and New Features
5051
-----------------------------

‎libcxx/docs/Status/Cxx23Papers.csv

Copy file name to clipboardExpand all lines: libcxx/docs/Status/Cxx23Papers.csv
+1-1Lines 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.0",""
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.0",""
2525
"","","","","",""
26-
"`P0288R9 <https://wg21.link/P0288R9>`__","``any_invocable``","2021-10 (Virtual)","","",""
26+
"`P0288R9 <https://wg21.link/P0288R9>`__","LWG","``move_only_function``","October 2021","|Complete|","20.0"
2727
"`P0798R8 <https://wg21.link/P0798R8>`__","Monadic operations for ``std::optional``","2021-10 (Virtual)","|Complete|","14.0",""
2828
"`P0849R8 <https://wg21.link/P0849R8>`__","``auto(x)``: ``DECAY_COPY`` in the language","2021-10 (Virtual)","|Complete|","14.0",""
2929
"`P1072R10 <https://wg21.link/P1072R10>`__","``basic_string::resize_and_overwrite``","2021-10 (Virtual)","|Complete|","14.0",""

‎libcxx/include/CMakeLists.txt

Copy file name to clipboardExpand all lines: libcxx/include/CMakeLists.txt
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ set(files
409409
__functional/is_transparent.h
410410
__functional/mem_fn.h
411411
__functional/mem_fun_ref.h
412+
__functional/move_only_function.h
413+
__functional/move_only_function_common.h
414+
__functional/move_only_function_impl.h
412415
__functional/not_fn.h
413416
__functional/operations.h
414417
__functional/perfect_forward.h

‎libcxx/include/__configuration/abi.h

Copy file name to clipboardExpand all lines: libcxx/include/__configuration/abi.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@
124124
// This setting disables the addition of such artificial padding, leading to a more optimal
125125
// representation for several types.
126126
# define _LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING
127+
// Enable clang::trivial_abi for std::move_only_function
128+
# define _LIBCPP_ABI_SMALL_BUFFER_TRIVIAL_ABI
127129
#elif _LIBCPP_ABI_VERSION == 1
128130
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
129131
// Enable compiling copies of now inline methods into the dylib to support
+97Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
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 that should be stored is trivially relocatable (currently only when it is trivially move constructible and
24+
// trivially destructible). There is also a bool in the lower bits of the vptr stored which is set when the contained
25+
// object is not trivially 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 mostly used to store a functor. To only
30+
// forward functors there is C++26's std::function_ref.
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 also allows storing a std::string or std::vector inside the small buffer (once the compiler
34+
// has full support of trivially_relocatable annotations).
35+
//
36+
// trivially-destructible bit: This allows us to keep the overall binary size smaller because we don't have to store
37+
// a pointer to a noop function inside the vtable. It also avoids loading the vtable during destruction, potentially
38+
// resulting in fewer cache misses. The downside is that calling the function now also requires setting the lower bits
39+
// of the pointer to zero, but this is a very fast operation on modern CPUs.
40+
//
41+
// interaction with copyable_function: When converting a copyable_function into a move_only_function we want to avoid
42+
// wrapping the copyable_function inside the move_only_function to avoid a double indirection. Instead, we copy the
43+
// small buffer and use copyable_function's vtable.
44+
45+
// NOLINTBEGIN(readability-duplicate-include)
46+
# define _LIBCPP_IN_MOVE_ONLY_FUNCTION_H
47+
48+
# include <__functional/move_only_function_impl.h>
49+
50+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
51+
# include <__functional/move_only_function_impl.h>
52+
53+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
54+
# include <__functional/move_only_function_impl.h>
55+
56+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
57+
# include <__functional/move_only_function_impl.h>
58+
59+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
60+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
61+
# include <__functional/move_only_function_impl.h>
62+
63+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
64+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
65+
# include <__functional/move_only_function_impl.h>
66+
67+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
68+
# include <__functional/move_only_function_impl.h>
69+
70+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
71+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &
72+
# include <__functional/move_only_function_impl.h>
73+
74+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
75+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
76+
# include <__functional/move_only_function_impl.h>
77+
78+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
79+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
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+
# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT true
88+
# define _LIBCPP_MOVE_ONLY_FUNCTION_CV const
89+
# define _LIBCPP_MOVE_ONLY_FUNCTION_REF &&
90+
# include <__functional/move_only_function_impl.h>
91+
92+
# undef _LIBCPP_IN_MOVE_ONLY_FUNCTION_H
93+
// NOLINTEND(readability-duplicate-include)
94+
95+
#endif // _LIBCPP_STD_VER >= 23 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
96+
97+
#endif // _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_H
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
_LIBCPP_BEGIN_NAMESPACE_STD
19+
20+
template <class...>
21+
class move_only_function;
22+
23+
template <class>
24+
inline constexpr bool __is_move_only_function_v = false;
25+
26+
template <class... _Args>
27+
inline constexpr bool __is_move_only_function_v<move_only_function<_Args...>> = true;
28+
29+
template <class _BufferT, class _ReturnT, class... _ArgTypes>
30+
struct _MoveOnlyFunctionTrivialVTable {
31+
using _CallFunc = _ReturnT(_BufferT&, _ArgTypes...);
32+
33+
_CallFunc* __call_;
34+
};
35+
36+
template <class _BufferT, class _ReturnT, class... _ArgTypes>
37+
struct _MoveOnlyFunctionNonTrivialVTable : _MoveOnlyFunctionTrivialVTable<_BufferT, _ReturnT, _ArgTypes...> {
38+
using _DestroyFunc = void(_BufferT&) noexcept;
39+
40+
_DestroyFunc* __destroy_;
41+
};
42+
43+
_LIBCPP_END_NAMESPACE_STD
44+
45+
#endif // _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.