@@ -1288,10 +1288,26 @@ struct converter {
12881288 template <class T >
12891289 operator T () && noexcept (
12901290 std::is_nothrow_invocable_r_v<T, F, std::in_place_type_t <T>>)
1291- requires(std::is_invocable_r_v<T, F, std::in_place_type_t <T>>)
1291+ requires(std::is_invocable_r_v<T, F, std::in_place_type_t <T>> &&
1292+ !std::is_invocable_r_v<T, F, std::in_place_type_t <T&>> &&
1293+ !std::is_invocable_r_v<T, F, std::in_place_type_t <T &&>>)
12921294 {
12931295 return std::move (f_)(std::in_place_type<T>);
12941296 }
1297+ template <class T >
1298+ operator T&() && noexcept (
1299+ std::is_nothrow_invocable_r_v<T&, F, std::in_place_type_t <T&>>)
1300+ requires (std::is_invocable_r_v<T&, F, std::in_place_type_t <T&>>)
1301+ {
1302+ return std::move (f_)(std::in_place_type<T&>);
1303+ }
1304+ template <class T >
1305+ operator T&&() && noexcept (
1306+ std::is_nothrow_invocable_r_v<T&&, F, std::in_place_type_t <T&&>>)
1307+ requires (std::is_invocable_r_v<T &&, F, std::in_place_type_t <T &&>>)
1308+ {
1309+ return std::move (f_)(std::in_place_type<T&&>);
1310+ }
12951311
12961312private:
12971313 F f_;
@@ -2346,14 +2362,29 @@ struct sign {
23462362template <std::size_t N>
23472363sign (const char (&str)[N]) -> sign<N - 1u>;
23482364
2349- struct wildcard {
2350- wildcard () = delete ;
2365+ // When std::reference_constructs_from_temporary_v (C++23) is not available, we
2366+ // fall back to a conservative approximation that disallows binding a temporary
2367+ // to a reference type if the source type is not a reference or if the source
2368+ // and target reference types are not compatible.
2369+ template <class T , class U >
2370+ concept explicitly_convertible =
2371+ std::is_constructible_v<U, T> &&
2372+ #if __cpp_lib_reference_from_temporary >= 202202L
2373+ !std::reference_constructs_from_temporary_v<U, T>;
2374+ #else
2375+ (!std::is_reference_v<U> ||
2376+ (std::is_reference_v<T> &&
2377+ std::is_convertible_v<std::add_pointer_t <std::remove_reference_t <T>>,
2378+ std::add_pointer_t <std::remove_reference_t <U>>>));
2379+ #endif // __cpp_lib_reference_from_temporary >= 202202L
23512380
2381+ struct noreturn_conversion {
23522382 template <class T >
2353- [[noreturn]] operator T () const {
2383+ [[noreturn]] PRO4D_STATIC_CALL (T, std:: in_place_type_t <T>) {
23542384 PROD_UNREACHABLE ();
23552385 }
23562386};
2387+ using wildcard = converter<noreturn_conversion>;
23572388
23582389} // namespace details
23592390
@@ -2577,9 +2608,9 @@ struct explicit_conversion_dispatch : details::cast_dispatch_base<true, false> {
25772608 PRO4D_STATIC_CALL (auto , T&& self) noexcept {
25782609 return details::converter{
25792610 [&self]<class U >(std::in_place_type_t <U>) noexcept (
2580- std::is_nothrow_constructible_v<U, T>)
2581- requires (std::is_constructible_v<U, T >)
2582- { return U{ std::forward<T>(self)} ; }};
2611+ std::is_nothrow_constructible_v<U, T>) -> U
2612+ requires (details::explicitly_convertible < T &&, U >)
2613+ { return static_cast <U>( std::forward<T>(self)) ; }};
25832614 }
25842615};
25852616using conversion_dispatch = explicit_conversion_dispatch;
0 commit comments