From 4b9c76ba6e541102fdaa1e5839e65e014c49263f Mon Sep 17 00:00:00 2001 From: dywoq Date: Mon, 30 Jun 2025 22:27:37 +0300 Subject: [PATCH 01/39] [libcxx] add ranges::enable_view> = true and format_kind> = range_format::disabled --- libcxx/.clangd | 2 ++ libcxx/include/optional | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 libcxx/.clangd diff --git a/libcxx/.clangd b/libcxx/.clangd new file mode 100644 index 0000000000000..8a80936175292 --- /dev/null +++ b/libcxx/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: [--std=c++2c] \ No newline at end of file diff --git a/libcxx/include/optional b/libcxx/include/optional index fa32d75ef86dd..f7d27c673fa52 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -102,6 +102,8 @@ namespace std { class optional { public: using value_type = T; + using iterator = implementation-defined; // see [optional.iterators] // since C++26 + using const_iterator = implementation-defined; // see [optional.iterators] // since C++26 // [optional.ctor], constructors constexpr optional() noexcept; @@ -135,6 +137,12 @@ namespace std { // [optional.swap], swap void swap(optional &) noexcept(see below ); // constexpr in C++20 + // [optional.iterators], iterator support + constexpr iterator begin() noexcept; // since C++26 + constexpr const_iterator begin() const noexcept; // since C++26 + constexpr iterator end() noexcept; // since C++26 + constexpr const_iterator end() const noexcept; // since C++26 + // [optional.observe], observers constexpr T const *operator->() const noexcept; constexpr T *operator->() noexcept; @@ -173,6 +181,11 @@ namespace std { template optional(T) -> optional; + template + constexpr bool ranges::enable_view> = true; // since C++26 + template + constexpr auto format_kind> = range_format::disabled; // since C++26 + } // namespace std */ @@ -187,6 +200,7 @@ namespace std { # include <__concepts/invocable.h> # include <__config> # include <__exception/exception.h> +# include <__format/range_default_formatter.h> # include <__functional/hash.h> # include <__functional/invoke.h> # include <__functional/unary_function.h> @@ -578,6 +592,14 @@ struct __is_std_optional : false_type {}; template struct __is_std_optional> : true_type {}; +# if _LIBCPP_STD_VER >= 26 +template +constexpr bool ranges::enable_view> = true; + +template +constexpr auto format_kind> = range_format::disabled; +# endif + template class _LIBCPP_DECLSPEC_EMPTY_BASES optional : private __optional_move_assign_base<_Tp>, From ebda4e4e97c46deae63f1139aa84016b704308b7 Mon Sep 17 00:00:00 2001 From: dywoq Date: Mon, 30 Jun 2025 22:39:17 +0300 Subject: [PATCH 02/39] [libcxx] add forward declaration of __optional_iterator in --- libcxx/include/optional | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index f7d27c673fa52..ccd06c7c9f5e7 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -102,7 +102,7 @@ namespace std { class optional { public: using value_type = T; - using iterator = implementation-defined; // see [optional.iterators] // since C++26 + using iterator = implementation-defined; // see [optional.iterators] // since C++26 using const_iterator = implementation-defined; // see [optional.iterators] // since C++26 // [optional.ctor], constructors @@ -580,6 +580,15 @@ using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG = template class optional; +# if _LIBCPP_STD_VER >= 26 + +enum class __optional_iterator_kind { not_as_const, as_const }; + +template <__optional_iterator_kind _Kind> +class __optional_iterator; + +# endif // _LIBCPP_STD_VER >= 26 + # if _LIBCPP_STD_VER >= 20 template @@ -593,12 +602,14 @@ template struct __is_std_optional> : true_type {}; # if _LIBCPP_STD_VER >= 26 + template constexpr bool ranges::enable_view> = true; template constexpr auto format_kind> = range_format::disabled; -# endif + +# endif // _LIBCPP_STD_VER >= 26 template class _LIBCPP_DECLSPEC_EMPTY_BASES optional @@ -610,6 +621,13 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES optional public: using value_type = _Tp; +# if _LIBCPP_STD_VER >= 26 + + using iterator = __optional_iterator<__optional_iterator_kind::not_as_const>; + using const_iterator = __optional_iterator<__optional_iterator_kind::as_const>; + +# endif // _LIBCPP_STD_VER >= 26 + using __trivially_relocatable _LIBCPP_NODEBUG = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>; using __replaceable _LIBCPP_NODEBUG = conditional_t<__is_replaceable_v<_Tp>, optional, void>; From 6e97c3411107ac5bf8d926f4a1a5f99fae1f2958 Mon Sep 17 00:00:00 2001 From: dywoq Date: Mon, 30 Jun 2025 22:54:22 +0300 Subject: [PATCH 03/39] [libcxx] add __optional_iterator --- libcxx/include/optional | 55 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index ccd06c7c9f5e7..c5fe9370262a9 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -584,7 +584,7 @@ class optional; enum class __optional_iterator_kind { not_as_const, as_const }; -template <__optional_iterator_kind _Kind> +template class __optional_iterator; # endif // _LIBCPP_STD_VER >= 26 @@ -609,6 +609,59 @@ constexpr bool ranges::enable_view> = true; template constexpr auto format_kind> = range_format::disabled; +template +class __optional_iterator { +public: + using value_type = _Tp; + using difference_type = std::ptrdiff_t; + using pointer = _Tp*; + using reference = _Tp&; + using iterator_category = std::forward_iterator_tag; + +private: + pointer __ptr_; + _LIBCPP_HIDE_FROM_ABI explicit __optional_iterator(pointer __ptr) : __ptr_(__ptr) {} + _LIBCPP_HIDE_FROM_ABI friend class optional>; + _LIBCPP_HIDE_FROM_ABI friend class optional; + +public: + _LIBCPP_HIDE_FROM_ABI __optional_iterator() : __ptr_(nullptr) {} + + _LIBCPP_HIDE_FROM_ABI __optional_iterator(const __optional_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI __optional_iterator& operator=(const __optional_iterator&) = default; + + _LIBCPP_HIDE_FROM_ABI reference operator*() const { + if (__ptr_ == nullptr) + throw std::runtime_error("dereferencing end iterator"); + return *__ptr_; + } + + _LIBCPP_HIDE_FROM_ABI reference operator->() const { + if (__ptr_ == nullptr) + throw std::runtime_error("dereferencing end iterator"); + return *__ptr_; + } + + _LIBCPP_HIDE_FROM_ABI __optional_iterator operator++() { + __ptr_ = nullptr; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI __optional_iterator operator++(int) { + __optional_iterator __tmp = *this; + __ptr_ = nullptr; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI bool operator==(const __optional_iterator& __other) const { return __ptr_ == __other.__ptr_; } + _LIBCPP_HIDE_FROM_ABI bool operator!=(const __optional_iterator& __other) const { return __ptr_ != __other.__ptr_; } + + template + _LIBCPP_HIDE_FROM_ABI operator __optional_iterator() const { + return __optional_iterator(static_cast(__ptr_)); + } +}; + # endif // _LIBCPP_STD_VER >= 26 template From ef525626d0a8cb55c47b597fc47ee758421daf91 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 10:32:44 +0300 Subject: [PATCH 04/39] [libcxxx] add begin() and end() to std::optional class --- libcxx/include/optional | 44 +++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index c5fe9370262a9..edca0003f687b 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -582,9 +582,7 @@ class optional; # if _LIBCPP_STD_VER >= 26 -enum class __optional_iterator_kind { not_as_const, as_const }; - -template +template class __optional_iterator; # endif // _LIBCPP_STD_VER >= 26 @@ -609,7 +607,7 @@ constexpr bool ranges::enable_view> = true; template constexpr auto format_kind> = range_format::disabled; -template +template class __optional_iterator { public: using value_type = _Tp; @@ -632,17 +630,17 @@ public: _LIBCPP_HIDE_FROM_ABI reference operator*() const { if (__ptr_ == nullptr) - throw std::runtime_error("dereferencing end iterator"); + std::__throw_runtime_error("deferencering end iterator"); return *__ptr_; } - _LIBCPP_HIDE_FROM_ABI reference operator->() const { + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { if (__ptr_ == nullptr) - throw std::runtime_error("dereferencing end iterator"); + std::__throw_runtime_error("deferencering end iterator"); return *__ptr_; } - _LIBCPP_HIDE_FROM_ABI __optional_iterator operator++() { + _LIBCPP_HIDE_FROM_ABI __optional_iterator& operator++() { __ptr_ = nullptr; return *this; } @@ -656,9 +654,11 @@ public: _LIBCPP_HIDE_FROM_ABI bool operator==(const __optional_iterator& __other) const { return __ptr_ == __other.__ptr_; } _LIBCPP_HIDE_FROM_ABI bool operator!=(const __optional_iterator& __other) const { return __ptr_ != __other.__ptr_; } - template - _LIBCPP_HIDE_FROM_ABI operator __optional_iterator() const { - return __optional_iterator(static_cast(__ptr_)); + template + _LIBCPP_HIDE_FROM_ABI operator __optional_iterator() const + requires(!std::is_const_v<_Ut>) + { + return __optional_iterator(static_cast(__ptr_)); } }; @@ -676,8 +676,8 @@ public: # if _LIBCPP_STD_VER >= 26 - using iterator = __optional_iterator<__optional_iterator_kind::not_as_const>; - using const_iterator = __optional_iterator<__optional_iterator_kind::as_const>; + using iterator = __optional_iterator<_Tp>; + using const_iterator = __optional_iterator<_Tp>; # endif // _LIBCPP_STD_VER >= 26 @@ -1069,6 +1069,24 @@ public: } # endif // _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 26 + + _LIBCPP_HIDE_FROM_ABI iterator begin() { + if (!this->has_value()) + return this->end(); + return iterator(reinterpret_cast<_Tp*>(this->__get())); + } + _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { + if (!this->has_value()) + return this->end(); + return const_iterator(reinterpret_cast<_Tp*>(this->value())); + } + + _LIBCPP_HIDE_FROM_ABI iterator end() { return iterator(nullptr); } + _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return const_iterator(nullptr); } + +# endif + using __base::reset; }; From 820d96c67320eeffb67d595441558079aaaa899f Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 10:59:18 +0300 Subject: [PATCH 05/39] [libcxx] update includes in header --- libcxx/include/optional | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index edca0003f687b..235a6682d6448 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -137,7 +137,7 @@ namespace std { // [optional.swap], swap void swap(optional &) noexcept(see below ); // constexpr in C++20 - // [optional.iterators], iterator support + // [optional.iterators], iterator support constexpr iterator begin() noexcept; // since C++26 constexpr const_iterator begin() const noexcept; // since C++26 constexpr iterator end() noexcept; // since C++26 @@ -200,6 +200,7 @@ namespace std { # include <__concepts/invocable.h> # include <__config> # include <__exception/exception.h> +# include <__format/format_context.h> # include <__format/range_default_formatter.h> # include <__functional/hash.h> # include <__functional/invoke.h> From 5fc696bdc95883892b04fd6f076095ffc141ea1d Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:00:10 +0300 Subject: [PATCH 06/39] [libcxx] add comment --- libcxx/include/optional | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/optional b/libcxx/include/optional index 235a6682d6448..1942d0ce14336 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -1070,6 +1070,7 @@ public: } # endif // _LIBCPP_STD_VER >= 23 +// P3168R2 # if _LIBCPP_STD_VER >= 26 _LIBCPP_HIDE_FROM_ABI iterator begin() { From 162170ce8c1cee4e170e8995a2dfd49967593416 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:03:46 +0300 Subject: [PATCH 07/39] [libcxx] remove unimplemented: True parameter in generate_feature_test_macro_components.py --- libcxx/utils/generate_feature_test_macro_components.py | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index edd7b124a1fb3..7be4880428d58 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -1004,7 +1004,6 @@ def add_version_header(tc): "name": "__cpp_lib_optional_range_support", "values": {"c++26": 202406}, # P3168R2 Give std::optional Range Support "headers": ["optional"], - "unimplemented": True, }, { "name": "__cpp_lib_out_ptr", From f968252c6a6c8e098832e873a9223ec31f7e5449 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:07:48 +0300 Subject: [PATCH 08/39] [libcxx] update header --- libcxx/docs/FeatureTestMacroTable.rst | 2 +- libcxx/include/version | 2 +- .../optional.version.compile.pass.cpp | 16 +++++----------- .../version.version.compile.pass.cpp | 16 +++++----------- 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 3c635e5e46bbd..28e8f805e1843 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -476,7 +476,7 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_not_fn`` ``202306L`` ---------------------------------------------------------- ----------------- - ``__cpp_lib_optional_range_support`` *unimplemented* + ``__cpp_lib_optional_range_support`` ``202406L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_out_ptr`` ``202311L`` ---------------------------------------------------------- ----------------- diff --git a/libcxx/include/version b/libcxx/include/version index 91fe48351e161..6096185efc865 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -581,7 +581,7 @@ __cpp_lib_void_t 201411L # define __cpp_lib_mdspan 202406L # undef __cpp_lib_not_fn # define __cpp_lib_not_fn 202306L -// # define __cpp_lib_optional_range_support 202406L +# define __cpp_lib_optional_range_support 202406L # undef __cpp_lib_out_ptr # define __cpp_lib_out_ptr 202311L // # define __cpp_lib_philox_engine 202406L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp index 32685972d6019..ece2fe81b7c13 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp @@ -152,17 +152,11 @@ # error "__cpp_lib_optional should have the value 202110L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should be defined in c++26" -# endif -# if __cpp_lib_optional_range_support != 202406L -# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should be defined in c++26" +# endif +# if __cpp_lib_optional_range_support != 202406L +# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" # endif #endif // TEST_STD_VER > 23 diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index e546719142231..09063e5a80e17 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -7377,17 +7377,11 @@ # error "__cpp_lib_optional should have the value 202110L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should be defined in c++26" -# endif -# if __cpp_lib_optional_range_support != 202406L -# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should be defined in c++26" +# endif +# if __cpp_lib_optional_range_support != 202406L +# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" # endif # ifndef __cpp_lib_out_ptr From 06109ed45e53775186e4074a126174d65e95708f Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:45:28 +0300 Subject: [PATCH 09/39] [libcxx] write optional.range tests --- .../optional.range/iteration.pass.cpp | 20 +++++++++++++++++++ .../satisfies_range_concept.pass.cpp | 19 ++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp create mode 100644 libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp diff --git a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp new file mode 100644 index 0000000000000..8ab1c099d30b5 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: std-at-least-c++26 + +#include +#include + +int main() { + std::optional val = 2; + for (const auto& elem : val) { + std::cout << elem << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp new file mode 100644 index 0000000000000..96ba4c0903067 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp @@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: std-at-least-c++26 + +#include +#include +#include + +int main() { + bool status = std::ranges::range>; + std::cout << "std::ranges::range> is " << status << std::endl; + return 0; +} \ No newline at end of file From fc75fe044d7070fafe6b4f27c8ca71fad84137ca Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:54:27 +0300 Subject: [PATCH 10/39] [libcxx] add optional.range.runtime_error.fail test --- .../optional.range/runtime_error.fail.cpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp diff --git a/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp b/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp new file mode 100644 index 0000000000000..7e27fbf0d1f22 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: std-at-least-c++26 + +#include +#include + +int main() { + std::optional val = 2; + auto end = val.end(); + auto s = *end; + (void)s; + return 0; +} \ No newline at end of file From f9395288e1252bfd4b8705b38bec4fa9ee61dfe6 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:58:10 +0300 Subject: [PATCH 11/39] [libcxx] remove unused include --- ...runtime_error.fail.cpp => runtime_error.compile.fail.cpp} | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename libcxx/test/std/utilities/optional/optional.range/{runtime_error.fail.cpp => runtime_error.compile.fail.cpp} (87%) diff --git a/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp b/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp similarity index 87% rename from libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp rename to libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp index 7e27fbf0d1f22..554fbd8af37fa 100644 --- a/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp @@ -8,13 +8,12 @@ // UNSUPPORTED: std-at-least-c++26 -#include +#include "../../../../support/assert_macros.h" #include int main() { std::optional val = 2; auto end = val.end(); - auto s = *end; - (void)s; + TEST_DOES_NOT_THROW(*end); return 0; } \ No newline at end of file From fdc917b0d87ed8504c25fc5a86ad2b3eb224d0d1 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:58:32 +0300 Subject: [PATCH 12/39] [libcxx] change path to assert_macros.h --- .../optional/optional.range/runtime_error.compile.fail.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp b/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp index 554fbd8af37fa..fa74c2b477efd 100644 --- a/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp @@ -8,7 +8,7 @@ // UNSUPPORTED: std-at-least-c++26 -#include "../../../../support/assert_macros.h" +#include "assert_macros.h" #include int main() { From e704aba28045f536888caed99d246a3c7238bbb1 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 11:59:25 +0300 Subject: [PATCH 13/39] [libcxx] remove .clangd --- libcxx/.clangd | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 libcxx/.clangd diff --git a/libcxx/.clangd b/libcxx/.clangd deleted file mode 100644 index 8a80936175292..0000000000000 --- a/libcxx/.clangd +++ /dev/null @@ -1,2 +0,0 @@ -CompileFlags: - Add: [--std=c++2c] \ No newline at end of file From f294f986a71f574d0fb87c3306c3672d564a7c77 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 12:02:52 +0300 Subject: [PATCH 14/39] [libcxx] rename test --- .../{runtime_error.compile.fail.cpp => runtime_error.fail.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libcxx/test/std/utilities/optional/optional.range/{runtime_error.compile.fail.cpp => runtime_error.fail.cpp} (100%) diff --git a/libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp b/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp similarity index 100% rename from libcxx/test/std/utilities/optional/optional.range/runtime_error.compile.fail.cpp rename to libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp From a720391ab78b447a0e18b94efa50329a144a250f Mon Sep 17 00:00:00 2001 From: dywoq <138208549+dywoq@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:39:17 +0300 Subject: [PATCH 15/39] [libcxx] change iterator_category to random_access_iterator_tag Co-authored-by: A. Jiang --- libcxx/include/optional | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index 1942d0ce14336..62718da9d775a 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -615,7 +615,8 @@ public: using difference_type = std::ptrdiff_t; using pointer = _Tp*; using reference = _Tp&; - using iterator_category = std::forward_iterator_tag; + using iterator_category = random_access_iterator_tag; + using iterator_concept = contiguous_iterator_tag; private: pointer __ptr_; From 4bfc9bbfa4f4710e13b2b284b826a547d1b4e87d Mon Sep 17 00:00:00 2001 From: dywoq <138208549+dywoq@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:43:34 +0300 Subject: [PATCH 16/39] [libcxx] remove operator!= for __optional_iterator in Co-authored-by: A. Jiang --- libcxx/include/optional | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index 62718da9d775a..4d4f69dbacbcf 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -654,7 +654,6 @@ public: } _LIBCPP_HIDE_FROM_ABI bool operator==(const __optional_iterator& __other) const { return __ptr_ == __other.__ptr_; } - _LIBCPP_HIDE_FROM_ABI bool operator!=(const __optional_iterator& __other) const { return __ptr_ != __other.__ptr_; } template _LIBCPP_HIDE_FROM_ABI operator __optional_iterator() const From 26974eb40fb08d8efe2737de4f5d4f2ad273714e Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 15:11:33 +0300 Subject: [PATCH 17/39] [libcxx] add constexpr to __optional_iterator, optional::begin and optional::end --- libcxx/include/optional | 43 +++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index 4d4f69dbacbcf..a8a88a1614b07 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -620,43 +620,36 @@ public: private: pointer __ptr_; - _LIBCPP_HIDE_FROM_ABI explicit __optional_iterator(pointer __ptr) : __ptr_(__ptr) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_iterator(pointer __ptr) : __ptr_(__ptr) {} _LIBCPP_HIDE_FROM_ABI friend class optional>; _LIBCPP_HIDE_FROM_ABI friend class optional; public: - _LIBCPP_HIDE_FROM_ABI __optional_iterator() : __ptr_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator() : __ptr_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI __optional_iterator(const __optional_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI __optional_iterator& operator=(const __optional_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator(const __optional_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator=(const __optional_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI reference operator*() const { - if (__ptr_ == nullptr) - std::__throw_runtime_error("deferencering end iterator"); - return *__ptr_; - } - - _LIBCPP_HIDE_FROM_ABI pointer operator->() const { - if (__ptr_ == nullptr) - std::__throw_runtime_error("deferencering end iterator"); - return *__ptr_; - } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__ptr_; } + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return *__ptr_; } - _LIBCPP_HIDE_FROM_ABI __optional_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() { __ptr_ = nullptr; return *this; } - _LIBCPP_HIDE_FROM_ABI __optional_iterator operator++(int) { + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator++(int) { __optional_iterator __tmp = *this; __ptr_ = nullptr; return __tmp; } - _LIBCPP_HIDE_FROM_ABI bool operator==(const __optional_iterator& __other) const { return __ptr_ == __other.__ptr_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const __optional_iterator& __other) const { + return __ptr_ == __other.__ptr_; + } template - _LIBCPP_HIDE_FROM_ABI operator __optional_iterator() const + _LIBCPP_HIDE_FROM_ABI constexpr operator __optional_iterator() const requires(!std::is_const_v<_Ut>) { return __optional_iterator(static_cast(__ptr_)); @@ -1073,19 +1066,19 @@ public: // P3168R2 # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI iterator begin() { + _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() { if (!this->has_value()) return this->end(); - return iterator(reinterpret_cast<_Tp*>(this->__get())); + return iterator(static_cast<_Tp*>(this->__get())); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const { if (!this->has_value()) return this->end(); - return const_iterator(reinterpret_cast<_Tp*>(this->value())); + return const_iterator(static_cast<_Tp*>(this->value())); } - _LIBCPP_HIDE_FROM_ABI iterator end() { return iterator(nullptr); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return const_iterator(nullptr); } + _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(nullptr); } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { return const_iterator(nullptr); } # endif From b61f90bc76c5d604655b034a664bf5c0b3452e10 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 15:19:26 +0300 Subject: [PATCH 18/39] [libcxx] use assert in optional.range.iteration.pass test --- .../utilities/optional/optional.range/iteration.pass.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp index 8ab1c099d30b5..5e5265d7cc86e 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp @@ -8,13 +8,12 @@ // UNSUPPORTED: std-at-least-c++26 -#include +#include #include int main() { std::optional val = 2; - for (const auto& elem : val) { - std::cout << elem << std::endl; - } + for (const auto& elem : val) + assert(elem == 2); return 0; } \ No newline at end of file From 6993061ee65e60054fdd661faf668c8c7ea95454 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 15:33:14 +0300 Subject: [PATCH 19/39] [libcxx] use static_assert in optional.range.satisfies_range_concept.pass test --- .../utilities/optional/optional.range/iteration.pass.cpp | 2 +- .../optional.range/satisfies_range_concept.pass.cpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp index 5e5265d7cc86e..a3c3af9d44adf 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp @@ -16,4 +16,4 @@ int main() { for (const auto& elem : val) assert(elem == 2); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp index 96ba4c0903067..9b8a3712ac7dc 100644 --- a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp @@ -8,12 +8,10 @@ // UNSUPPORTED: std-at-least-c++26 -#include #include #include int main() { - bool status = std::ranges::range>; - std::cout << "std::ranges::range> is " << status << std::endl; + static_assert(std::ranges::range>, "std::ranges::range> is false"); return 0; -} \ No newline at end of file +} From a3ef155d0594101e1a43018fdd59dd166abd0784 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 16:11:37 +0300 Subject: [PATCH 20/39] [libcxx] add additional operators to __optional_iterator --- libcxx/.clangd | 2 ++ libcxx/include/optional | 66 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 libcxx/.clangd diff --git a/libcxx/.clangd b/libcxx/.clangd new file mode 100644 index 0000000000000..8a80936175292 --- /dev/null +++ b/libcxx/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: [--std=c++2c] \ No newline at end of file diff --git a/libcxx/include/optional b/libcxx/include/optional index a8a88a1614b07..65ef2022440fe 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -633,21 +633,77 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__ptr_; } _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return *__ptr_; } - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() noexcept { __ptr_ = nullptr; return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator++(int) noexcept { + auto __t = *this; + __ptr_ = nullptr; + return __t; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator--() noexcept { + __ptr_ = nullptr; + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator--(int) noexcept { + auto __t = *this; + __ptr_ = nullptr; + return __t; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator+=(difference_type __n) noexcept { + if (__n != 0) + __ptr_ = nullptr; + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator-=(difference_type __n) noexcept { + if (__n != 0) + __ptr_ = nullptr; + return *this; + } - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator++(int) { - __optional_iterator __tmp = *this; - __ptr_ = nullptr; - return __tmp; + _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator + operator+(__optional_iterator __i, difference_type __n) noexcept { + return (__n == 0 ? __i : __optional_iterator{}); + } + _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator + operator+(difference_type __n, __optional_iterator __i) noexcept { + return __i + __n; + } + _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator + operator-(__optional_iterator __i, difference_type __n) noexcept { + return (__n == 0 ? __i : __optional_iterator{}); } + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(__optional_iterator __a, __optional_iterator __b) noexcept { + return (__a.__ptr_ == __b.__ptr_ ? 0 : (__a.__ptr_ ? 1 : -1)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const noexcept { return *(*this + __n); } _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const __optional_iterator& __other) const { return __ptr_ == __other.__ptr_; } + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator<(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { + return __a.__ptr_ < __b.__ptr_; + } + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator>(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { + return __a.__ptr_ > __b.__ptr_; + } + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator<=(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { + return __a.__ptr_ <= __b.__ptr_; + } + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator>=(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { + return __a.__ptr_ >= __b.__ptr_; + } + template _LIBCPP_HIDE_FROM_ABI constexpr operator __optional_iterator() const requires(!std::is_const_v<_Ut>) From 6d4be2177cdcfdd39bba9af5d712d297fd891d63 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 16:12:49 +0300 Subject: [PATCH 21/39] [libcxx] remove .clangd --- libcxx/.clangd | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 libcxx/.clangd diff --git a/libcxx/.clangd b/libcxx/.clangd deleted file mode 100644 index 8a80936175292..0000000000000 --- a/libcxx/.clangd +++ /dev/null @@ -1,2 +0,0 @@ -CompileFlags: - Add: [--std=c++2c] \ No newline at end of file From 47ba8682e4e5f61b38abbeb4b845be230e3c31f9 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 16:32:47 +0300 Subject: [PATCH 22/39] [libcxx] add iterator_types.verify test to optional.ranges --- .../optional.range/iterator_types.verify.cpp | 28 +++++++++++++++++++ ...cpp => satisfies_range_concept.verify.cpp} | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp rename libcxx/test/std/utilities/optional/optional.range/{satisfies_range_concept.pass.cpp => satisfies_range_concept.verify.cpp} (81%) diff --git a/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp b/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp new file mode 100644 index 0000000000000..c4e35aa727f5c --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: std-at-least-c++26 + +#include +#include + +int main() { + using Iter = std::optional::iterator; + + std::iterator_traits s; + static_assert(std::random_access_iterator); + static_assert(std::contiguous_iterator); + + static_assert(std::is_same_v::value_type, int>); + static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); + static_assert(std::is_same_v::pointer, int*>); + static_assert(std::is_same_v::reference, int&>); + static_assert( + std::is_same_v::iterator_category, std::random_access_iterator_tag>); + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.verify.cpp similarity index 81% rename from libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp rename to libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.verify.cpp index 9b8a3712ac7dc..907e482a81115 100644 --- a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.verify.cpp @@ -12,6 +12,6 @@ #include int main() { - static_assert(std::ranges::range>, "std::ranges::range> is false"); + static_assert(std::ranges::range>); return 0; } From 3f69edaef08c0c860b348d748f3667b3f72d777a Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 16:37:02 +0300 Subject: [PATCH 23/39] [libcxx] add missing new character line at EOF --- .../utilities/optional/optional.range/iterator_types.verify.cpp | 2 +- .../utilities/optional/optional.range/runtime_error.fail.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp b/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp index c4e35aa727f5c..09d3c9d0274d7 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp @@ -25,4 +25,4 @@ int main() { static_assert( std::is_same_v::iterator_category, std::random_access_iterator_tag>); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp b/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp index fa74c2b477efd..c0ed1a4b62426 100644 --- a/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp @@ -16,4 +16,4 @@ int main() { auto end = val.end(); TEST_DOES_NOT_THROW(*end); return 0; -} \ No newline at end of file +} From ef8af0aa35f6a463da71abe8c0dc4b0cec531d4f Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 16:49:28 +0300 Subject: [PATCH 24/39] [libcxx] change optional.range.iteration.pass test to constant eveluated --- libcxx/include/optional | 8 -------- .../optional/optional.range/iteration.pass.cpp | 12 +++++++++--- ...ntime_error.fail.cpp => runtime_error.verify.cpp} | 0 3 files changed, 9 insertions(+), 11 deletions(-) rename libcxx/test/std/utilities/optional/optional.range/{runtime_error.fail.cpp => runtime_error.verify.cpp} (100%) diff --git a/libcxx/include/optional b/libcxx/include/optional index 65ef2022440fe..ae65c7c1be7c2 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -200,7 +200,6 @@ namespace std { # include <__concepts/invocable.h> # include <__config> # include <__exception/exception.h> -# include <__format/format_context.h> # include <__format/range_default_formatter.h> # include <__functional/hash.h> # include <__functional/invoke.h> @@ -581,13 +580,6 @@ using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG = template class optional; -# if _LIBCPP_STD_VER >= 26 - -template -class __optional_iterator; - -# endif // _LIBCPP_STD_VER >= 26 - # if _LIBCPP_STD_VER >= 20 template diff --git a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp index a3c3af9d44adf..ff9b0602c2a5e 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp @@ -11,9 +11,15 @@ #include #include -int main() { - std::optional val = 2; +constexpr bool test() { + constexpr std::optional val = 2; for (const auto& elem : val) - assert(elem == 2); + if (elem != 2) + return false; + return true; +} + +int main() { + static_assert(test()); return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp b/libcxx/test/std/utilities/optional/optional.range/runtime_error.verify.cpp similarity index 100% rename from libcxx/test/std/utilities/optional/optional.range/runtime_error.fail.cpp rename to libcxx/test/std/utilities/optional/optional.range/runtime_error.verify.cpp From 04b551120779bdd61eff0b0af69b40b3c51bd8ec Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 17:01:23 +0300 Subject: [PATCH 25/39] [libcxx] use __wrap_iter in __optional_iterator --- libcxx/.clangd | 2 ++ libcxx/include/optional | 73 ++++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 libcxx/.clangd diff --git a/libcxx/.clangd b/libcxx/.clangd new file mode 100644 index 0000000000000..8a80936175292 --- /dev/null +++ b/libcxx/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: [--std=c++2c] \ No newline at end of file diff --git a/libcxx/include/optional b/libcxx/include/optional index ae65c7c1be7c2..e2e008c2fffb1 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -205,6 +205,7 @@ namespace std { # include <__functional/invoke.h> # include <__functional/unary_function.h> # include <__fwd/functional.h> +# include <__iterator/wrap_iter.h> # include <__memory/addressof.h> # include <__memory/construct_at.h> # include <__tuple/sfinae_helpers.h> @@ -602,63 +603,65 @@ constexpr auto format_kind> = range_format::disabled; template class __optional_iterator { + using _Base = __wrap_iter<_Tp*>; + _Base __it_; + public: using value_type = _Tp; - using difference_type = std::ptrdiff_t; - using pointer = _Tp*; - using reference = _Tp&; + using difference_type = typename _Base::difference_type; + using pointer = typename _Base::pointer; + using reference = typename _Base::reference; using iterator_category = random_access_iterator_tag; using iterator_concept = contiguous_iterator_tag; private: - pointer __ptr_; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_iterator(pointer __ptr) : __ptr_(__ptr) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_iterator(_Base __it) noexcept : __it_(__it) {} _LIBCPP_HIDE_FROM_ABI friend class optional>; _LIBCPP_HIDE_FROM_ABI friend class optional; public: - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator() : __ptr_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator() : __it_(_Base()) {} _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator(const __optional_iterator&) = default; _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator=(const __optional_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__ptr_; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return *__ptr_; } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__it_; } + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return *__it_.operator->(); } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() noexcept { - __ptr_ = nullptr; + __it_ = _Base(); return *this; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator++(int) noexcept { - auto __t = *this; - __ptr_ = nullptr; - return __t; + auto __tmp = *this; + __it_ = _Base(); + return __tmp; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator--() noexcept { - __ptr_ = nullptr; + __it_ = _Base(); return *this; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator--(int) noexcept { - auto __t = *this; - __ptr_ = nullptr; - return __t; + auto __tmp = *this; + __it_ = _Base(); + return __tmp; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator+=(difference_type __n) noexcept { if (__n != 0) - __ptr_ = nullptr; + __it_ = _Base(); return *this; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator-=(difference_type __n) noexcept { if (__n != 0) - __ptr_ = nullptr; + __it_ = _Base(); return *this; } _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator operator+(__optional_iterator __i, difference_type __n) noexcept { - return (__n == 0 ? __i : __optional_iterator{}); + return (__n == 0 ? __i : __optional_iterator(_Base())); } _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator operator+(difference_type __n, __optional_iterator __i) noexcept { @@ -666,41 +669,41 @@ public: } _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator operator-(__optional_iterator __i, difference_type __n) noexcept { - return (__n == 0 ? __i : __optional_iterator{}); + return (__n == 0 ? __i : __optional_iterator(_Base())); } _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__optional_iterator __a, __optional_iterator __b) noexcept { - return (__a.__ptr_ == __b.__ptr_ ? 0 : (__a.__ptr_ ? 1 : -1)); + return (__a.__it_ == __b.__it_ ? 0 : (__a.__it_ ? 1 : -1)); } _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const noexcept { return *(*this + __n); } _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const __optional_iterator& __other) const { - return __ptr_ == __other.__ptr_; + return __it_ == __other.__it_; } _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__ptr_ < __b.__ptr_; + return __a.__it_ < __b.__it_; } _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__ptr_ > __b.__ptr_; + return __a.__it_ > __b.__it_; } _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__ptr_ <= __b.__ptr_; + return __a.__it_ <= __b.__it_; } _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__ptr_ >= __b.__ptr_; + return __a.__it_ >= __b.__it_; } template _LIBCPP_HIDE_FROM_ABI constexpr operator __optional_iterator() const requires(!std::is_const_v<_Ut>) { - return __optional_iterator(static_cast(__ptr_)); + return __optional_iterator(__wrap_iter{__it_.base()}); } }; @@ -1116,17 +1119,21 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() { if (!this->has_value()) - return this->end(); - return iterator(static_cast<_Tp*>(this->__get())); + return end(); + return iterator(__wrap_iter(static_cast<_Tp*>(this->__get()))); } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const { if (!this->has_value()) - return this->end(); - return const_iterator(static_cast<_Tp*>(this->value())); + return end(); + return const_iterator(__wrap_iter(static_cast(this->__get()))); } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(nullptr); } - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { return const_iterator(nullptr); } + _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(__wrap_iter(static_cast<_Tp*>(nullptr))); } + + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { + return const_iterator(__wrap_iter(static_cast(nullptr))); + } # endif From 3f6f45779647131c99a015166282d7f775f09dba Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 17:02:09 +0300 Subject: [PATCH 26/39] [libcxx] add missing comment --- libcxx/include/optional | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index e2e008c2fffb1..0fa036e18e36b 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -1135,7 +1135,7 @@ public: return const_iterator(__wrap_iter(static_cast(nullptr))); } -# endif +# endif // _LIBCPP_STD_VER >= 26 using __base::reset; }; From 132bc39206d5e95be7f5d75a9ad3d0151977d4fa Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 17:10:52 +0300 Subject: [PATCH 27/39] [libcxx] add tests enable_ranges_view.pass and format_kind.pass in optional.range --- .../optional.range/enable_ranges_view.pass.cpp | 17 +++++++++++++++++ .../optional.range/format_kind.pass.cpp | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.pass.cpp create mode 100644 libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp diff --git a/libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.pass.cpp new file mode 100644 index 0000000000000..2337e93e22128 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.pass.cpp @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: std-at-least-c++26 + +#include +#include + +int main() { + static_assert(std::ranges::enable_view>); + return 0; +} diff --git a/libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp new file mode 100644 index 0000000000000..2d77a5fae3695 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: std-at-least-c++26 + +#include +#include + +int main() { + static_assert(std::format_kind>); + return 0; +} From 8c4d4dfd493ffdc47ca1d35e9d4e21c66846a867 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 17:11:25 +0300 Subject: [PATCH 28/39] [libcxx] remove .clangd --- libcxx/.clangd | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 libcxx/.clangd diff --git a/libcxx/.clangd b/libcxx/.clangd deleted file mode 100644 index 8a80936175292..0000000000000 --- a/libcxx/.clangd +++ /dev/null @@ -1,2 +0,0 @@ -CompileFlags: - Add: [--std=c++2c] \ No newline at end of file From ef032f16289ddf6125624be04957d393c732851a Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 17:31:22 +0300 Subject: [PATCH 29/39] [libcxx] add friend declarations for __wrap_iter in __optional_iterator --- libcxx/include/optional | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcxx/include/optional b/libcxx/include/optional index 0fa036e18e36b..1adc812254cc8 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -616,6 +616,10 @@ public: private: _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_iterator(_Base __it) noexcept : __it_(__it) {} + + _LIBCPP_HIDE_FROM_ABI friend class __wrap_iter<_Tp*>; + _LIBCPP_HIDE_FROM_ABI friend class __wrap_iter; + _LIBCPP_HIDE_FROM_ABI friend class optional>; _LIBCPP_HIDE_FROM_ABI friend class optional; From 149ff9e10333008e3452d0f1e009aa10df5dcefd Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 18:11:27 +0300 Subject: [PATCH 30/39] [libcxx] update const_iterator type to use const reference in optional --- libcxx/include/optional | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index 1adc812254cc8..5f5af5374efc0 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -726,7 +726,7 @@ public: # if _LIBCPP_STD_VER >= 26 using iterator = __optional_iterator<_Tp>; - using const_iterator = __optional_iterator<_Tp>; + using const_iterator = __optional_iterator; # endif // _LIBCPP_STD_VER >= 26 From 0510945043fbc88165249f72ffada4b99b0099b3 Mon Sep 17 00:00:00 2001 From: dywoq Date: Tue, 1 Jul 2025 18:20:37 +0300 Subject: [PATCH 31/39] [libcxx] simplify __optional_iterator operations and add to_address utility --- libcxx/include/optional | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index 5f5af5374efc0..58a0d080ab428 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -630,42 +630,40 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator=(const __optional_iterator&) = default; _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__it_; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return *__it_.operator->(); } + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return __it_.operator->(); } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() noexcept { - __it_ = _Base(); + ++__it_; return *this; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator++(int) noexcept { auto __tmp = *this; - __it_ = _Base(); + ++__it_; return __tmp; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator--() noexcept { - __it_ = _Base(); + --__it_; return *this; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator--(int) noexcept { auto __tmp = *this; - __it_ = _Base(); + --__it_; return __tmp; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator+=(difference_type __n) noexcept { - if (__n != 0) - __it_ = _Base(); + __it_ += __n; return *this; } _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator-=(difference_type __n) noexcept { - if (__n != 0) - __it_ = _Base(); + __it_ -= __n; return *this; } _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator operator+(__optional_iterator __i, difference_type __n) noexcept { - return (__n == 0 ? __i : __optional_iterator(_Base())); + return __optional_iterator(__i.__it_ + __n); } _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator operator+(difference_type __n, __optional_iterator __i) noexcept { @@ -673,14 +671,14 @@ public: } _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator operator-(__optional_iterator __i, difference_type __n) noexcept { - return (__n == 0 ? __i : __optional_iterator(_Base())); + return __optional_iterator(__i.__it_ - __n); } _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__optional_iterator __a, __optional_iterator __b) noexcept { - return (__a.__it_ == __b.__it_ ? 0 : (__a.__it_ ? 1 : -1)); + return __a.__it_ - __b.__it_; } - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const noexcept { return *(*this + __n); } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const noexcept { return *(__it_ + __n); } _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const __optional_iterator& __other) const { return __it_ == __other.__it_; @@ -710,6 +708,10 @@ public: return __optional_iterator(__wrap_iter{__it_.base()}); } }; +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp* to_address(const __optional_iterator<_Tp>& __it) noexcept { + return std::to_address(__it.__it_); +} # endif // _LIBCPP_STD_VER >= 26 From 5be2e9d053cc92b23e150243ce5a2b8fba5453ca Mon Sep 17 00:00:00 2001 From: dywoq Date: Wed, 2 Jul 2025 11:30:44 +0300 Subject: [PATCH 32/39] [libcxx] rename enable_ranges_view.pass.cpp to enable_ranges_view.compile.pass.cpp --- ...e_ranges_view.pass.cpp => enable_ranges_view.compile.pass.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libcxx/test/std/utilities/optional/optional.range/{enable_ranges_view.pass.cpp => enable_ranges_view.compile.pass.cpp} (100%) diff --git a/libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.compile.pass.cpp similarity index 100% rename from libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.pass.cpp rename to libcxx/test/std/utilities/optional/optional.range/enable_ranges_view.compile.pass.cpp From e34c3bc57056ce4d7b4bac83e28c690142336c73 Mon Sep 17 00:00:00 2001 From: dywoq Date: Wed, 2 Jul 2025 18:38:27 +0300 Subject: [PATCH 33/39] [libcxx] rename optional.range tests --- ...{iterator_types.verify.cpp => iterator_types.compile.pass.cpp} | 0 ...oncept.verify.cpp => satisfies_range_concept.compile.pass.cpp} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename libcxx/test/std/utilities/optional/optional.range/{iterator_types.verify.cpp => iterator_types.compile.pass.cpp} (100%) rename libcxx/test/std/utilities/optional/optional.range/{satisfies_range_concept.verify.cpp => satisfies_range_concept.compile.pass.cpp} (100%) diff --git a/libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp b/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp similarity index 100% rename from libcxx/test/std/utilities/optional/optional.range/iterator_types.verify.cpp rename to libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp diff --git a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.verify.cpp b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp similarity index 100% rename from libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.verify.cpp rename to libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp From fc0219ec8b47ad36d19ad78cad16ef803711b1c3 Mon Sep 17 00:00:00 2001 From: dywoq Date: Wed, 2 Jul 2025 18:42:07 +0300 Subject: [PATCH 34/39] [libcxx] remove main function blocks in optional.range.*.compile.pass tests --- ....pass.cpp => format_kind.compile.pass.cpp} | 5 +--- .../iterator_types.compile.pass.cpp | 24 +++++++------------ .../satisfies_range_concept.compile.pass.cpp | 5 +--- 3 files changed, 10 insertions(+), 24 deletions(-) rename libcxx/test/std/utilities/optional/optional.range/{format_kind.pass.cpp => format_kind.compile.pass.cpp} (84%) diff --git a/libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/format_kind.compile.pass.cpp similarity index 84% rename from libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp rename to libcxx/test/std/utilities/optional/optional.range/format_kind.compile.pass.cpp index 2d77a5fae3695..3d812f251fc75 100644 --- a/libcxx/test/std/utilities/optional/optional.range/format_kind.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/format_kind.compile.pass.cpp @@ -11,7 +11,4 @@ #include #include -int main() { - static_assert(std::format_kind>); - return 0; -} +static_assert(std::format_kind>); diff --git a/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp index 09d3c9d0274d7..b203a21bfc0e6 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp @@ -8,21 +8,13 @@ // UNSUPPORTED: std-at-least-c++26 -#include -#include +using Iter = std::optional::iterator; -int main() { - using Iter = std::optional::iterator; +static_assert(std::random_access_iterator); +static_assert(std::contiguous_iterator); - std::iterator_traits s; - static_assert(std::random_access_iterator); - static_assert(std::contiguous_iterator); - - static_assert(std::is_same_v::value_type, int>); - static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); - static_assert(std::is_same_v::pointer, int*>); - static_assert(std::is_same_v::reference, int&>); - static_assert( - std::is_same_v::iterator_category, std::random_access_iterator_tag>); - return 0; -} +static_assert(std::is_same_v::value_type, int>); +static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); +static_assert(std::is_same_v::pointer, int*>); +static_assert(std::is_same_v::reference, int&>); +static_assert(std::is_same_v::iterator_category, std::random_access_iterator_tag>); diff --git a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp index 907e482a81115..dc3f02420945c 100644 --- a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp @@ -11,7 +11,4 @@ #include #include -int main() { - static_assert(std::ranges::range>); - return 0; -} +static_assert(std::ranges::range>); From b0393d67201ebd831e7715a988082f0aa8011b11 Mon Sep 17 00:00:00 2001 From: dywoq Date: Wed, 2 Jul 2025 19:25:18 +0300 Subject: [PATCH 35/39] [libcxx] update satisfies_range_concept test to include sized_range, common_range, and contiguous_range assertions for std::optional --- .../optional.range/satisfies_range_concept.compile.pass.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp index dc3f02420945c..8559526074b97 100644 --- a/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/satisfies_range_concept.compile.pass.cpp @@ -11,4 +11,6 @@ #include #include -static_assert(std::ranges::range>); +static_assert(std::ranges::sized_range>); +static_assert(std::ranges::common_range>); +static_assert(std::ranges::contiguous_range>); From d66ea581725c2ed6e77f295fa7b2a7e2729ad7c0 Mon Sep 17 00:00:00 2001 From: dywoq Date: Wed, 2 Jul 2025 19:37:17 +0300 Subject: [PATCH 36/39] [libcxx] remove __optional_iterator class --- libcxx/include/__iterator/wrap_iter.h | 4 + libcxx/include/optional | 130 ++------------------------ 2 files changed, 11 insertions(+), 123 deletions(-) diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h index 2b5bc489dd44c..1a6f73da993cb 100644 --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -117,6 +117,10 @@ class __wrap_iter { friend class span; template friend struct array; +#if _LIBCPP_STD_VER >= 26 + template + friend class optional; +#endif }; template diff --git a/libcxx/include/optional b/libcxx/include/optional index 58a0d080ab428..425f88d592d52 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -601,119 +601,7 @@ constexpr bool ranges::enable_view> = true; template constexpr auto format_kind> = range_format::disabled; -template -class __optional_iterator { - using _Base = __wrap_iter<_Tp*>; - _Base __it_; - -public: - using value_type = _Tp; - using difference_type = typename _Base::difference_type; - using pointer = typename _Base::pointer; - using reference = typename _Base::reference; - using iterator_category = random_access_iterator_tag; - using iterator_concept = contiguous_iterator_tag; - -private: - _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_iterator(_Base __it) noexcept : __it_(__it) {} - - _LIBCPP_HIDE_FROM_ABI friend class __wrap_iter<_Tp*>; - _LIBCPP_HIDE_FROM_ABI friend class __wrap_iter; - - _LIBCPP_HIDE_FROM_ABI friend class optional>; - _LIBCPP_HIDE_FROM_ABI friend class optional; - -public: - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator() : __it_(_Base()) {} - - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator(const __optional_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator=(const __optional_iterator&) = default; - - _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__it_; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return __it_.operator->(); } - - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() noexcept { - ++__it_; - return *this; - } - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator++(int) noexcept { - auto __tmp = *this; - ++__it_; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator--() noexcept { - --__it_; - return *this; - } - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator operator--(int) noexcept { - auto __tmp = *this; - --__it_; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator+=(difference_type __n) noexcept { - __it_ += __n; - return *this; - } - _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator-=(difference_type __n) noexcept { - __it_ -= __n; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator - operator+(__optional_iterator __i, difference_type __n) noexcept { - return __optional_iterator(__i.__it_ + __n); - } - _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator - operator+(difference_type __n, __optional_iterator __i) noexcept { - return __i + __n; - } - _LIBCPP_HIDE_FROM_ABI friend constexpr __optional_iterator - operator-(__optional_iterator __i, difference_type __n) noexcept { - return __optional_iterator(__i.__it_ - __n); - } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type - operator-(__optional_iterator __a, __optional_iterator __b) noexcept { - return __a.__it_ - __b.__it_; - } - - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const noexcept { return *(__it_ + __n); } - - _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const __optional_iterator& __other) const { - return __it_ == __other.__it_; - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator<(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__it_ < __b.__it_; - } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator>(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__it_ > __b.__it_; - } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator<=(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__it_ <= __b.__it_; - } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator>=(const __optional_iterator& __a, const __optional_iterator& __b) noexcept { - return __a.__it_ >= __b.__it_; - } - - template - _LIBCPP_HIDE_FROM_ABI constexpr operator __optional_iterator() const - requires(!std::is_const_v<_Ut>) - { - return __optional_iterator(__wrap_iter{__it_.base()}); - } -}; -template -_LIBCPP_HIDE_FROM_ABI constexpr _Tp* to_address(const __optional_iterator<_Tp>& __it) noexcept { - return std::to_address(__it.__it_); -} - -# endif // _LIBCPP_STD_VER >= 26 +# endif template class _LIBCPP_DECLSPEC_EMPTY_BASES optional @@ -726,10 +614,8 @@ public: using value_type = _Tp; # if _LIBCPP_STD_VER >= 26 - - using iterator = __optional_iterator<_Tp>; - using const_iterator = __optional_iterator; - + using iterator = __wrap_iter<_Tp>; + using const_iterator = __wrap_iter; # endif // _LIBCPP_STD_VER >= 26 using __trivially_relocatable _LIBCPP_NODEBUG = @@ -1126,20 +1012,18 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() { if (!this->has_value()) return end(); - return iterator(__wrap_iter(static_cast<_Tp*>(this->__get()))); + return iterator(static_cast<_Tp>(this->__get())); } _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const { if (!this->has_value()) return end(); - return const_iterator(__wrap_iter(static_cast(this->__get()))); + return const_iterator(static_cast(this->__get())); } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(__wrap_iter(static_cast<_Tp*>(nullptr))); } + _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(static_cast<_Tp>(nullptr)); } - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { - return const_iterator(__wrap_iter(static_cast(nullptr))); - } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { return const_iterator(static_cast(nullptr)); } # endif // _LIBCPP_STD_VER >= 26 From 42de74be44b3bc41249f23d4ed5c269b740609f8 Mon Sep 17 00:00:00 2001 From: dywoq Date: Wed, 2 Jul 2025 19:45:13 +0300 Subject: [PATCH 37/39] [libcxx] refactor iterator type assertions in optional.range --- .../iterator_types.compile.pass.cpp | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp index b203a21bfc0e6..277264d0d9b54 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iterator_types.compile.pass.cpp @@ -8,13 +8,30 @@ // UNSUPPORTED: std-at-least-c++26 -using Iter = std::optional::iterator; +#include +#include +#include +#include -static_assert(std::random_access_iterator); -static_assert(std::contiguous_iterator); +using iterator = std::optional::iterator; +using const_iterator = std::optional::const_iterator; -static_assert(std::is_same_v::value_type, int>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::pointer, int*>); -static_assert(std::is_same_v::reference, int&>); -static_assert(std::is_same_v::iterator_category, std::random_access_iterator_tag>); +// iterator + +static_assert(std::random_access_iterator); +static_assert(std::contiguous_iterator); +static_assert(std::is_same_v::value_type, int>); +static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); +static_assert(std::is_same_v::pointer, int*>); +static_assert(std::is_same_v::reference, int&>); +static_assert(std::is_same_v::iterator_category, std::random_access_iterator_tag>); + +// const iterator + +static_assert(std::random_access_iterator); +static_assert(std::contiguous_iterator); +static_assert(std::is_same_v::value_type, int>); +static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); +static_assert(std::is_same_v::pointer, int*>); +static_assert(std::is_same_v::reference, int&>); +static_assert(std::is_same_v::iterator_category, std::random_access_iterator_tag>); From 99fb18940c8c6efabc46a76e84a94db3bef87e5c Mon Sep 17 00:00:00 2001 From: dywoq <138208549+dywoq@users.noreply.github.com> Date: Wed, 2 Jul 2025 20:42:49 +0300 Subject: [PATCH 38/39] [libcxx] use test() along with static_assert(test()) in optional.range.iteration.pass Co-authored-by: A. Jiang --- .../std/utilities/optional/optional.range/iteration.pass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp index ff9b0602c2a5e..41139544a68b4 100644 --- a/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.range/iteration.pass.cpp @@ -20,6 +20,7 @@ constexpr bool test() { } int main() { + test(); static_assert(test()); return 0; } From 02cd53f81a921a2b6dbf98e6ce8426a6023297c5 Mon Sep 17 00:00:00 2001 From: dywoq Date: Thu, 3 Jul 2025 19:24:04 +0300 Subject: [PATCH 39/39] [libcxx] correct iterator type to use pointer types in optional --- libcxx/include/optional | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libcxx/include/optional b/libcxx/include/optional index 425f88d592d52..25856cb56d75a 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -614,8 +614,8 @@ public: using value_type = _Tp; # if _LIBCPP_STD_VER >= 26 - using iterator = __wrap_iter<_Tp>; - using const_iterator = __wrap_iter; + using iterator = __wrap_iter<_Tp*>; + using const_iterator = __wrap_iter; # endif // _LIBCPP_STD_VER >= 26 using __trivially_relocatable _LIBCPP_NODEBUG = @@ -1012,18 +1012,18 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() { if (!this->has_value()) return end(); - return iterator(static_cast<_Tp>(this->__get())); + return iterator(static_cast<_Tp*>(this->__get())); } _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const { if (!this->has_value()) return end(); - return const_iterator(static_cast(this->__get())); + return const_iterator(static_cast(this->__get())); } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(static_cast<_Tp>(nullptr)); } + _LIBCPP_HIDE_FROM_ABI constexpr iterator end() { return iterator(static_cast<_Tp*>(nullptr)); } - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { return const_iterator(static_cast(nullptr)); } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const { return const_iterator(static_cast(nullptr)); } # endif // _LIBCPP_STD_VER >= 26