Skip to content

Commit 6609f9e

Browse files
committed
Implement P2988R12: Give optional range support
1 parent 50408ee commit 6609f9e

File tree

12 files changed

+246
-28
lines changed

12 files changed

+246
-28
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ Status
480480
---------------------------------------------------------- -----------------
481481
``__cpp_lib_not_fn`` ``202306L``
482482
---------------------------------------------------------- -----------------
483-
``__cpp_lib_optional_range_support`` *unimplemented*
483+
``__cpp_lib_optional_range_support`` ``202406L``
484484
---------------------------------------------------------- -----------------
485485
``__cpp_lib_out_ptr`` ``202311L``
486486
---------------------------------------------------------- -----------------

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Implemented Papers
5353
- P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
5454
- P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
5555
- P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
56-
56+
- P3168R2 Give ``std::optional`` Range Support (`Github <https://github.com/llvm/llvm-project/issues/105430>`__)
5757
Improvements and New Features
5858
-----------------------------
5959

libcxx/docs/Status/Cxx2cPapers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"`P2747R2 <https://wg21.link/P2747R2>`__","``constexpr`` placement new","2024-06 (St. Louis)","|Complete|","20",""
6767
"`P2997R1 <https://wg21.link/P2997R1>`__","Removing the common reference requirement from the indirectly invocable concepts","2024-06 (St. Louis)","|Complete|","19","Implemented as a DR against C++20. (MSVC STL and libstdc++ will do the same.)"
6868
"`P2389R2 <https://wg21.link/P2389R2>`__","``dextents`` Index Type Parameter","2024-06 (St. Louis)","|Complete|","19",""
69-
"`P3168R2 <https://wg21.link/P3168R2>`__","Give ``std::optional`` Range Support","2024-06 (St. Louis)","","",""
69+
"`P3168R2 <https://wg21.link/P3168R2>`__","Give ``std::optional`` Range Support","2024-06 (St. Louis)","","21","|Complete|"
7070
"`P3217R0 <https://wg21.link/P3217R0>`__","Adjoints to 'Enabling list-initialization for algorithms': find_last","2024-06 (St. Louis)","","",""
7171
"`P2985R0 <https://wg21.link/P2985R0>`__","A type trait for detecting virtual base classes","2024-06 (St. Louis)","|Complete|","20",""
7272
"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","","",""

libcxx/include/__iterator/wrap_iter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +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;
120122
};
121123

122124
template <class _Iter1>

libcxx/include/optional

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ namespace std {
2020
template <class T>
2121
class optional;
2222
23+
template<class T>
24+
constexpr bool ranges::enable_view<optional<T>> = true;
25+
template<class T>
26+
constexpr auto format_kind<optional<T>> = range_format::disabled;
27+
2328
template<class T>
2429
concept is-derived-from-optional = requires(const T& t) { // exposition only
2530
[]<class U>(const optional<U>&){ }(t);
@@ -102,6 +107,8 @@ namespace std {
102107
class optional {
103108
public:
104109
using value_type = T;
110+
using iterator = implementation-defined; // see [optional.iterators]
111+
using const_iterator = implementation-defined; // see [optional.iterators]
105112
106113
// [optional.ctor], constructors
107114
constexpr optional() noexcept;
@@ -135,6 +142,12 @@ namespace std {
135142
// [optional.swap], swap
136143
void swap(optional &) noexcept(see below ); // constexpr in C++20
137144
145+
// [optional.iterators], iterator support
146+
constexpr iterator begin() noexcept;
147+
constexpr const_iterator begin() const noexcept;
148+
constexpr iterator end() noexcept;
149+
constexpr const_iterator end() const noexcept;
150+
138151
// [optional.observe], observers
139152
constexpr T const *operator->() const noexcept;
140153
constexpr T *operator->() noexcept;
@@ -233,6 +246,13 @@ namespace std {
233246
# include <initializer_list>
234247
# include <version>
235248

249+
# if _LIBCPP_STD_VER >= 26
250+
# include <__cstddef/ptrdiff_t.h>
251+
# include <__format/range_format.h>
252+
# include <__iterator/wrap_iter.h>
253+
# include <__ranges/enable_view.h>
254+
# endif
255+
236256
// standard-mandated includes
237257

238258
// [optional.syn]
@@ -567,6 +587,14 @@ using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG =
567587
template <class _Tp>
568588
class optional;
569589

590+
# if _LIBCPP_STD_VER >= 26
591+
template <class _Tp>
592+
constexpr bool ranges::enable_view<optional<_Tp>> = true;
593+
594+
template <class _Tp>
595+
constexpr range_format format_kind<optional<_Tp>> = range_format::disabled;
596+
# endif
597+
570598
# if _LIBCPP_STD_VER >= 20
571599

572600
template <class _Tp>
@@ -586,8 +614,17 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES optional
586614
private __optional_sfinae_assign_base_t<_Tp> {
587615
using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
588616

617+
# if _LIBCPP_STD_VER >= 26
618+
using pointer = std::add_pointer_t<std::remove_cvref_t<_Tp>>;
619+
using const_pointer = std::add_pointer_t<const std::remove_cvref_t<_Tp>>;
620+
# endif
621+
589622
public:
590623
using value_type = _Tp;
624+
# if _LIBCPP_STD_VER >= 26
625+
using iterator = __wrap_iter<pointer>;
626+
using const_iterator = __wrap_iter<const_pointer>;
627+
# endif
591628

592629
using __trivially_relocatable _LIBCPP_NODEBUG =
593630
conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
@@ -792,6 +829,18 @@ public:
792829
}
793830
}
794831

832+
# if _LIBCPP_STD_VER >= 26
833+
// [optional.iterators], iterator support
834+
_LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept { return iterator(std::addressof(this->__get())); }
835+
836+
_LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
837+
return const_iterator(std::addressof(this->__get()));
838+
}
839+
840+
_LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept { return begin() + this->has_value(); }
841+
_LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return begin() + this->has_value(); }
842+
# endif
843+
795844
_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
796845
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
797846
return std::addressof(this->__get());

libcxx/include/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ __cpp_lib_void_t 201411L <type_traits>
585585
# define __cpp_lib_mdspan 202406L
586586
# undef __cpp_lib_not_fn
587587
# define __cpp_lib_not_fn 202306L
588-
// # define __cpp_lib_optional_range_support 202406L
588+
# define __cpp_lib_optional_range_support 202406L
589589
# undef __cpp_lib_out_ptr
590590
# define __cpp_lib_out_ptr 202311L
591591
// # define __cpp_lib_philox_engine 202406L

libcxx/modules/std/optional.inc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@
1010
export namespace std {
1111
// [optional.optional], class template optional
1212
using std::optional;
13-
13+
#if _LIBCPP_STD_VER >= 26
14+
// [optional.iterators], iterator support
15+
namespace ranges {
16+
using std::ranges::enable_view;
17+
}
18+
#endif
1419
// [optional.nullopt], no-value state indicator
1520
using std::nullopt;
1621
using std::nullopt_t;
1722

1823
// [optional.bad.access], class bad_optional_access
1924
using std::bad_optional_access;
2025

26+
#if _LIBCPP_STD_VER >= 26
27+
using std::format_kind;
28+
#endif
29+
2130
// [optional.relops], relational operators
2231
using std::operator==;
2332
using std::operator!=;

libcxx/test/libcxx/transitive_includes/cxx26.csv

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ algorithm cctype
22
algorithm climits
33
algorithm compare
44
algorithm cstdint
5+
algorithm cstdio
56
algorithm cstring
67
algorithm ctime
78
algorithm cwchar
@@ -11,6 +12,8 @@ algorithm iosfwd
1112
algorithm limits
1213
algorithm optional
1314
algorithm ratio
15+
algorithm stdexcept
16+
algorithm string_view
1417
algorithm tuple
1518
algorithm version
1619
any cstdint
@@ -330,26 +333,32 @@ flat_map cctype
330333
flat_map climits
331334
flat_map compare
332335
flat_map cstdint
336+
flat_map cstdio
333337
flat_map cstring
334338
flat_map cwchar
335339
flat_map cwctype
336340
flat_map initializer_list
341+
flat_map iosfwd
337342
flat_map limits
338343
flat_map optional
339344
flat_map stdexcept
345+
flat_map string_view
340346
flat_map tuple
341347
flat_map version
342348
flat_set cctype
343349
flat_set climits
344350
flat_set compare
345351
flat_set cstdint
352+
flat_set cstdio
346353
flat_set cstring
347354
flat_set cwchar
348355
flat_set cwctype
349356
flat_set initializer_list
357+
flat_set iosfwd
350358
flat_set limits
351359
flat_set optional
352360
flat_set stdexcept
361+
flat_set string_view
353362
flat_set tuple
354363
flat_set version
355364
format array
@@ -417,13 +426,16 @@ functional array
417426
functional cctype
418427
functional compare
419428
functional cstdint
429+
functional cstdio
420430
functional cstring
421431
functional cwchar
422432
functional cwctype
423433
functional initializer_list
434+
functional iosfwd
424435
functional limits
425436
functional optional
426437
functional stdexcept
438+
functional string_view
427439
functional tuple
428440
functional typeinfo
429441
functional unordered_map
@@ -623,13 +635,16 @@ locale version
623635
map cctype
624636
map compare
625637
map cstdint
638+
map cstdio
626639
map cstring
627640
map cwchar
628641
map cwctype
629642
map initializer_list
643+
map iosfwd
630644
map limits
631645
map optional
632646
map stdexcept
647+
map string_view
633648
map tuple
634649
map version
635650
mdspan array
@@ -673,22 +688,36 @@ mutex typeinfo
673688
mutex version
674689
new version
675690
numbers version
691+
numeric cctype
676692
numeric climits
677693
numeric compare
678694
numeric cstdint
695+
numeric cstdio
679696
numeric cstring
680697
numeric ctime
698+
numeric cwchar
699+
numeric cwctype
681700
numeric initializer_list
701+
numeric iosfwd
682702
numeric limits
683703
numeric optional
684704
numeric ratio
705+
numeric stdexcept
706+
numeric string_view
685707
numeric tuple
686708
numeric version
709+
optional cctype
687710
optional compare
688711
optional cstdint
712+
optional cstdio
689713
optional cstring
714+
optional cwchar
715+
optional cwctype
690716
optional initializer_list
717+
optional iosfwd
691718
optional limits
719+
optional stdexcept
720+
optional string_view
692721
optional version
693722
ostream array
694723
ostream bitset
@@ -806,6 +835,7 @@ ranges limits
806835
ranges optional
807836
ranges span
808837
ranges stdexcept
838+
ranges string_view
809839
ranges tuple
810840
ranges variant
811841
ranges version
@@ -851,12 +881,16 @@ semaphore version
851881
set cctype
852882
set compare
853883
set cstdint
884+
set cstdio
854885
set cstring
855886
set cwchar
856887
set cwctype
857888
set initializer_list
889+
set iosfwd
858890
set limits
859891
set optional
892+
set stdexcept
893+
set string_view
860894
set tuple
861895
set version
862896
shared_mutex cerrno
@@ -1091,21 +1125,34 @@ typeindex typeinfo
10911125
typeindex version
10921126
typeinfo cstdint
10931127
typeinfo version
1128+
unordered_map cctype
10941129
unordered_map compare
10951130
unordered_map cstdint
1131+
unordered_map cstdio
10961132
unordered_map cstring
1133+
unordered_map cwchar
1134+
unordered_map cwctype
10971135
unordered_map initializer_list
1136+
unordered_map iosfwd
10981137
unordered_map limits
10991138
unordered_map optional
11001139
unordered_map stdexcept
1140+
unordered_map string_view
11011141
unordered_map tuple
11021142
unordered_map version
1143+
unordered_set cctype
11031144
unordered_set compare
11041145
unordered_set cstdint
1146+
unordered_set cstdio
11051147
unordered_set cstring
1148+
unordered_set cwchar
1149+
unordered_set cwctype
11061150
unordered_set initializer_list
1151+
unordered_set iosfwd
11071152
unordered_set limits
11081153
unordered_set optional
1154+
unordered_set stdexcept
1155+
unordered_set string_view
11091156
unordered_set tuple
11101157
unordered_set version
11111158
utility compare

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,11 @@
152152
# error "__cpp_lib_optional should have the value 202110L in c++26"
153153
# endif
154154

155-
# if !defined(_LIBCPP_VERSION)
156-
# ifndef __cpp_lib_optional_range_support
157-
# error "__cpp_lib_optional_range_support should be defined in c++26"
158-
# endif
159-
# if __cpp_lib_optional_range_support != 202406L
160-
# error "__cpp_lib_optional_range_support should have the value 202406L in c++26"
161-
# endif
162-
# else
163-
# ifdef __cpp_lib_optional_range_support
164-
# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!"
165-
# endif
155+
# ifndef __cpp_lib_optional_range_support
156+
# error "__cpp_lib_optional_range_support should be defined in c++26"
157+
# endif
158+
# if __cpp_lib_optional_range_support != 202406L
159+
# error "__cpp_lib_optional_range_support should have the value 202406L in c++26"
166160
# endif
167161

168162
#endif // TEST_STD_VER > 23

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7443,17 +7443,11 @@
74437443
# error "__cpp_lib_optional should have the value 202110L in c++26"
74447444
# endif
74457445

7446-
# if !defined(_LIBCPP_VERSION)
7447-
# ifndef __cpp_lib_optional_range_support
7448-
# error "__cpp_lib_optional_range_support should be defined in c++26"
7449-
# endif
7450-
# if __cpp_lib_optional_range_support != 202406L
7451-
# error "__cpp_lib_optional_range_support should have the value 202406L in c++26"
7452-
# endif
7453-
# else
7454-
# ifdef __cpp_lib_optional_range_support
7455-
# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!"
7456-
# endif
7446+
# ifndef __cpp_lib_optional_range_support
7447+
# error "__cpp_lib_optional_range_support should be defined in c++26"
7448+
# endif
7449+
# if __cpp_lib_optional_range_support != 202406L
7450+
# error "__cpp_lib_optional_range_support should have the value 202406L in c++26"
74577451
# endif
74587452

74597453
# ifndef __cpp_lib_out_ptr

0 commit comments

Comments
 (0)