Skip to content

Commit 389a23c

Browse files
authored
[libc++] Implement P2988R12: std::optional<T&> (#155202)
Resolves #148131 - Unlock `std::optional<T&>` implementation - Allow instantiations of `optional<T(&)(...)>` and `optional<T(&)[]>` but disables `value_or()` and `optional::iterator` + all `iterator` related functions - Update documentation - Update tests
1 parent 95f2728 commit 389a23c

Some content is hidden

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

41 files changed

+1176
-246
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ Status
486486
---------------------------------------------------------- -----------------
487487
``__cpp_lib_not_fn`` ``202306L``
488488
---------------------------------------------------------- -----------------
489+
``__cpp_lib_optional`` ``202506L``
490+
---------------------------------------------------------- -----------------
489491
``__cpp_lib_optional_range_support`` ``202406L``
490492
---------------------------------------------------------- -----------------
491493
``__cpp_lib_out_ptr`` ``202311L``

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Implemented Papers
4040

4141
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
4242
is implemented in this release)
43+
- P2988R12: ``std::optional<T&>`` (`Github <https://llvm.org/PR148131>`__)
4344
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
4445
- P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
4546
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)

libcxx/docs/Status/Cxx2cPapers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
"`P3293R3 <https://wg21.link/P3293R3>`__","Splicing a base class subobject","2025-06 (Sofia)","","","`#148125 <https://github.com/llvm/llvm-project/issues/148125>`__",""
123123
"`P3491R3 <https://wg21.link/P3491R3>`__","``define_static_{string,object,array}``","2025-06 (Sofia)","","","`#148126 <https://github.com/llvm/llvm-project/issues/148126>`__",""
124124
"`P3096R12 <https://wg21.link/P3096R12>`__","Function Parameter Reflection in Reflection for C++26","2025-06 (Sofia)","","","`#148127 <https://github.com/llvm/llvm-project/issues/148127>`__",""
125-
"`P2988R12 <https://wg21.link/P2988R12>`__","``std::optional<T&>``","2025-06 (Sofia)","","","`#148131 <https://github.com/llvm/llvm-project/issues/148131>`__",""
125+
"`P2988R12 <https://wg21.link/P2988R12>`__","``std::optional<T&>``","2025-06 (Sofia)","|Complete|","22","`#148131 <https://github.com/llvm/llvm-project/issues/148131>`__",""
126126
"`P3348R4 <https://wg21.link/P3348R4>`__","C++26 should refer to C23 not C17","2025-06 (Sofia)","","","`#148133 <https://github.com/llvm/llvm-project/issues/148133>`__",""
127127
"`P3037R6 <https://wg21.link/P3037R6>`__","``constexpr`` ``std::shared_ptr`` and friends","2025-06 (Sofia)","","","`#148135 <https://github.com/llvm/llvm-project/issues/148135>`__",""
128128
"`P3284R4 <https://wg21.link/P3284R4>`__","``write_env`` and ``unstoppable`` Sender Adaptors","2025-06 (Sofia)","","","`#148136 <https://github.com/llvm/llvm-project/issues/148136>`__",""

libcxx/include/__iterator/wrap_iter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ class __wrap_iter {
117117
friend class span;
118118
template <class _Tp, size_t _Size>
119119
friend struct array;
120-
template <class _Tp>
121-
friend class optional;
120+
template <class _Tp, class>
121+
friend struct __optional_iterator;
122122
};
123123

124124
template <class _Iter1>

libcxx/include/optional

Lines changed: 215 additions & 111 deletions
Large diffs are not rendered by default.

libcxx/include/version

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque>
187187
__cpp_lib_not_fn 202306L <functional>
188188
201603L // C++17
189189
__cpp_lib_null_iterators 201304L <iterator>
190-
__cpp_lib_optional 202110L <optional>
190+
__cpp_lib_optional 202506L <optional>
191+
202110L // C++23
191192
202106L // C++20
192193
201606L // C++17
193194
__cpp_lib_optional_range_support 202406L <optional>
@@ -594,6 +595,8 @@ __cpp_lib_void_t 201411L <type_traits>
594595
# define __cpp_lib_mdspan 202406L
595596
# undef __cpp_lib_not_fn
596597
# define __cpp_lib_not_fn 202306L
598+
# undef __cpp_lib_optional
599+
# define __cpp_lib_optional 202506L
597600
# define __cpp_lib_optional_range_support 202406L
598601
# undef __cpp_lib_out_ptr
599602
# define __cpp_lib_out_ptr 202311L

libcxx/modules/std/optional.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ export namespace std {
1313
#if _LIBCPP_STD_VER >= 26
1414
// [optional.iterators], iterator support
1515
namespace ranges {
16+
using std::ranges::enable_borrowed_range;
1617
using std::ranges::enable_view;
17-
}
18+
} // namespace ranges
1819
#endif
1920
// [optional.nullopt], no-value state indicator
2021
using std::nullopt;

libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ concept has_iterator_aliases = requires {
2323

2424
static_assert(has_iterator_aliases<std::optional<int>>);
2525
static_assert(has_iterator_aliases<std::optional<const int>>);
26-
27-
// TODO: Uncomment these once P2988R12 is implemented, as they would be testing optional<T&>
28-
29-
// static_assert(!has_iterator_aliases<std::optional<int (&)[]>>);
30-
// static_assert(!has_iterator_aliases<std::optional<void (&)(int, char)>>);
26+
static_assert(has_iterator_aliases<std::optional<int&>>);
27+
static_assert(has_iterator_aliases<std::optional<const int&>>);
28+
static_assert(!has_iterator_aliases<std::optional<int (&)[1]>>);
29+
static_assert(!has_iterator_aliases<std::optional<int (&)()>>);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// REQUIRES: std-at-least-c++26
11+
12+
// <optional>
13+
14+
// template <class U> T optional<T>::value_or(U&&);
15+
16+
#include <concepts>
17+
#include <optional>
18+
19+
template <typename Opt, typename T>
20+
concept has_value_or = requires(Opt opt, T&& t) {
21+
{ opt.value_or(t) } -> std::same_as<T>;
22+
};
23+
24+
static_assert(has_value_or<std::optional<int>, int>);
25+
static_assert(has_value_or<std::optional<int&>, int&>);
26+
static_assert(has_value_or<std::optional<const int&>, const int&>);
27+
static_assert(!has_value_or<std::optional<int (&)[1]>&&, int (&)[1]>);
28+
static_assert(!has_value_or<std::optional<int (&)()>&&, int (&)()>);

libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@
142142
# ifndef __cpp_lib_optional
143143
# error "__cpp_lib_optional should be defined in c++26"
144144
# endif
145-
# if __cpp_lib_optional != 202110L
146-
# error "__cpp_lib_optional should have the value 202110L in c++26"
145+
# if __cpp_lib_optional != 202506L
146+
# error "__cpp_lib_optional should have the value 202506L in c++26"
147147
# endif
148148

149149
# ifndef __cpp_lib_optional_range_support

0 commit comments

Comments
 (0)