@@ -34,6 +34,14 @@ template <> struct stdx::tombstone_traits<S> {
3434 constexpr auto operator ()() const { return S{-1 }; }
3535};
3636
37+ TEST_CASE (" tombstone detection" , " [optional]" ) {
38+ STATIC_REQUIRE (stdx::has_tombstone_v<E>);
39+ STATIC_REQUIRE (stdx::has_tombstone_v<S>);
40+ STATIC_REQUIRE (stdx::has_tombstone_v<float >);
41+ STATIC_REQUIRE (stdx::has_tombstone_v<int *>);
42+ STATIC_REQUIRE (not stdx::has_tombstone_v<int >);
43+ }
44+
3745TEST_CASE (" sizeof(optional<T>) == sizeof(T)" , " [optional]" ) {
3846 using O1 = stdx::optional<E>;
3947 STATIC_REQUIRE (sizeof (O1) == sizeof (E));
@@ -428,18 +436,31 @@ TEST_CASE("tombstone with non-structural value", "[optional]") {
428436}
429437#endif
430438
431- #if __cplusplus >= 202002L
432439namespace {
433440template <typename T>
434- using my_optional = stdx::conditional_t <requires {
435- typename stdx::tombstone_traits<T>::unspecialized;
436- }, std::optional<T>, stdx::optional<T>>;
441+ using my_optional = stdx::conditional_t <stdx::has_tombstone_v<T>,
442+ stdx::optional<T>, std::optional<T>>;
437443} // namespace
438444
439445TEST_CASE (" select optional implementation based on whether tombstone traits "
440446 " are present" ,
441447 " [optional]" ) {
442- static_assert (std::is_same_v<my_optional<S>, stdx::optional<S>>);
443- static_assert (std::is_same_v<my_optional<int >, std::optional<int >>);
448+ STATIC_REQUIRE (std::is_same_v<my_optional<S>, stdx::optional<S>>);
449+ STATIC_REQUIRE (std::is_same_v<my_optional<int >, std::optional<int >>);
450+ }
451+
452+ TEST_CASE (" product types have tombstones iff their components do" ,
453+ " [optional]" ) {
454+ STATIC_REQUIRE (not stdx::has_tombstone_v<std::tuple<>>);
455+ STATIC_REQUIRE (stdx::has_tombstone_v<std::tuple<E, S>>);
456+ STATIC_REQUIRE (not stdx::has_tombstone_v<std::tuple<int >>);
457+ STATIC_REQUIRE (stdx::has_tombstone_v<std::pair<E, S>>);
458+ }
459+
460+ TEST_CASE (" tombstone traits for product types come from components" ,
461+ " [optional]" ) {
462+ constexpr auto o = stdx::optional<std::tuple<E, S, float >>{};
463+ STATIC_REQUIRE (not o);
464+ STATIC_REQUIRE (*o == std::tuple{E{0xffu }, S{-1 },
465+ std::numeric_limits<float >::infinity ()});
444466}
445- #endif
0 commit comments