[libcxx-commits] [libcxx] [libc++] Correct `optional<T&>` implementation (PR #174537)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jan 7 10:46:17 PST 2026
================
@@ -32,40 +33,60 @@ struct Y
int test() const {return 2;}
};
-int main(int, char**)
-{
- {
- const optional<X> opt; ((void)opt);
- ASSERT_SAME_TYPE(decltype(*opt), X const&);
- ASSERT_NOEXCEPT(*opt);
- }
- {
- constexpr optional<X> opt(X{});
- static_assert((*opt).test() == 3, "");
- }
#if TEST_STD_VER >= 26
- {
- X x{};
- const optional<X&> opt{x};
- ASSERT_SAME_TYPE(decltype(*opt), X&);
- ASSERT_NOEXCEPT(*opt);
- }
- {
- X x{};
- const optional<const X&> opt{x};
- ASSERT_SAME_TYPE(decltype(*opt), const X&);
- ASSERT_NOEXCEPT(*opt);
- }
- {
- static constexpr X x{};
- constexpr optional<const X&> opt(x);
- static_assert((*opt).test() == 3);
- }
+constexpr bool test_ref() {
+ using T = TracedCopyMove;
+ {
+ T x{};
+ const std::optional<T&> opt(x);
+ ASSERT_NOEXCEPT(*opt);
+ ASSERT_SAME_TYPE(decltype(*opt), TracedCopyMove&);
+
+ assert(std::addressof(*opt) == std::addressof(x));
+ assert((*opt).constMove == 0);
+ assert((*opt).nonConstMove == 0);
+ assert((*opt).constCopy == 0);
+ assert((*opt).nonConstCopy == 0);
+ }
+
+ {
+ T x{};
+ const std::optional<const T&> opt(x);
+ ASSERT_NOEXCEPT(*opt);
+ ASSERT_SAME_TYPE(decltype(*opt), const TracedCopyMove&);
+
+ assert(std::addressof(*opt) == std::addressof(x));
+ assert((*opt).constMove == 0);
+ assert((*opt).nonConstMove == 0);
+ assert((*opt).constCopy == 0);
+ assert((*opt).nonConstCopy == 0);
+ }
+
+ return true;
+}
+
+#endif
+
+int main(int, char**) {
+ {
+ const optional<X> opt;
+ ((void)opt);
+ ASSERT_SAME_TYPE(decltype(*opt), X const&);
+ ASSERT_NOEXCEPT(*opt);
+ }
+ {
+ constexpr optional<X> opt(X{});
+ static_assert((*opt).test() == 3, "");
+ }
+ {
+ constexpr optional<Y> opt(Y{});
+ assert((*opt).test() == 2);
+ }
----------------
frederick-vs-ja wrote:
These 2 cases are suitable for both constant and runtime evaluation. I think we should use both `static_assert` and `assert` consistently.
(Top-level constant evaluation seems a bit mattering. So perhaps it makes some sense not to put them in `test_ref`.)
https://github.com/llvm/llvm-project/pull/174537
More information about the libcxx-commits
mailing list