[libcxx-commits] [libcxx] [libc++] Cooperation between `std::optional` and other standard types (PR #93672)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Apr 7 00:13:33 PDT 2025
================
@@ -359,8 +487,23 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> {
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) {
_LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
- std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...);
- this->__engaged_ = true;
+#ifdef _LIBCPP_ABI_COOPERATIVE_OPTIONAL
+ if constexpr (__optional::__cooperate<_Tp>::__do_cooperate()) {
+#if __has_builtin(__builtin_is_within_lifetime)
+ if consteval {
+ // No operations are ever done on a disengaged value. Ensure it is not destroyed.
+ std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...);
+ return;
+ }
+#endif
+ __optional::__cooperate<_Tp>::__construct_over(*std::launder(std::addressof(this->__val_)), std::forward<_Args>(__args)...);
----------------
frederick-vs-ja wrote:
I believe such technique doesn't work if `__builtin_is_within_lifetime` (or something used for implementing `std::is_within_lifetime`) is not available. `std::launder` can't be used for reading an inactive union member ([Godbolt link](https://godbolt.org/z/66qxoz3Pn)) as clarified by [LWG3495](https://cplusplus.github.io/LWG/issue3495).
IMO we should either
- just guard the whole optimization strategy with `__has_builtin(__builtin_is_within_lifetime)` (until all supported compilers have `__builtin_is_within_lifetime` implemented), or
- use `__builtin_constant_p` to check which member is active during constant evaluation.
`std::launder` doesn't seem useful in either case.
https://github.com/llvm/llvm-project/pull/93672
More information about the libcxx-commits
mailing list