[libcxx-commits] [libcxx] [libc++][NFC] Simplify some `optional.observe` tests (PR #175682)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jan 19 13:58:56 PST 2026
================
@@ -10,94 +10,126 @@
// <optional>
// constexpr T& optional<T>::operator*() &;
+// constexpr const T& optional<T>::operator*() const&;
+// constexpr T&& optional<T>::operator*() &&;
+// constexpr const T&& optional<T>::operator*() const&&;
+// constexpr T& optional<T&>::operator*() const;
#include <cassert>
#include <memory>
#include <optional>
+#include <utility>
#include "test_macros.h"
#if TEST_STD_VER >= 26
# include "copy_move_types.h"
#endif
-using std::optional;
-
-struct X
-{
- constexpr int test() const& {return 3;}
- int test() & {return 4;}
- constexpr int test() const&& {return 5;}
- int test() && {return 6;}
+struct X {
+ constexpr int test() const& { return 3; }
+ constexpr int test() & { return 4; }
+ constexpr int test() const&& { return 5; }
+ constexpr int test() && { return 6; }
};
-struct Y
-{
- constexpr int test() {return 7;}
-};
+template <typename T>
+constexpr void test_contract() {
+ std::optional<T> opt(T{});
+
+ ASSERT_SAME_TYPE(decltype(*opt), T&);
+ ASSERT_SAME_TYPE(decltype(*std::move(opt)), T&&);
+ ASSERT_SAME_TYPE(decltype(*std::as_const(opt)), const T&);
+ ASSERT_SAME_TYPE(decltype(*std::move(std::as_const(opt))), const T&&);
-constexpr int
-test()
-{
- optional<Y> opt{Y{}};
- return (*opt).test();
+ ASSERT_NOEXCEPT(*opt);
+ ASSERT_NOEXCEPT(*std::move(opt));
+ ASSERT_NOEXCEPT(*std::as_const(opt));
+ ASSERT_NOEXCEPT(*std::move(std::as_const(opt)));
}
#if TEST_STD_VER >= 26
-constexpr bool test_ref() {
+template <typename T>
+constexpr void test_ref_contract() {
+ std::optional<T&> opt;
+ ASSERT_SAME_TYPE(decltype(*opt), T&);
+ ASSERT_SAME_TYPE(decltype(*std::move(opt)), T&);
+ ASSERT_SAME_TYPE(decltype(*std::as_const(opt)), T&);
+ ASSERT_SAME_TYPE(decltype(*std::move(std::as_const(opt))), T&);
+
+ ASSERT_NOEXCEPT(*opt);
+ ASSERT_NOEXCEPT(*std::move(opt));
+ ASSERT_NOEXCEPT(*std::as_const(opt));
+ ASSERT_NOEXCEPT(*std::move(std::as_const(opt)));
+}
+#endif
+
+constexpr bool test() {
+ test_contract<int>();
+ test_contract<float>();
+ test_contract<double>();
+ test_contract<X>();
+ test_contract<const int>();
+ test_contract<const float>();
+ test_contract<const double>();
+ test_contract<const X>();
+
+ std::optional<X> opt{X{}};
+ {
+ assert((*std::as_const(opt)).test() == 3);
+ assert((*opt).test() == 4);
+ assert((*std::move(std::as_const(opt))).test() == 5);
+ assert((*std::move(opt)).test() == 6);
+ }
----------------
ldionne wrote:
For the non-reference optional, we don't test anywhere that we return a stable reference to the contained object. I'd add:
```c++
// Test that optional::operator* returns a stable reference to the contained value
{
std::optional<X> opt{X{}};
X& value = *opt;
assert(&value == &*opt);
}
```
https://github.com/llvm/llvm-project/pull/175682
More information about the libcxx-commits
mailing list