@@ -318,21 +318,38 @@ template <typename T, typename TS = tombstone_traits<T>> class optional {
318318
319319template <typename T> optional (T) -> optional<T>;
320320
321- template <typename F, typename ... Ts,
321+ namespace detail {
322+ template <typename T>
323+ constexpr bool optional_like =
324+ stdx::is_specialization_of_v<stdx::remove_cvref_t <T>, optional> or
325+ stdx::is_specialization_of_v<stdx::remove_cvref_t <T>, std::optional>;
326+
327+ template <typename R, typename ... Ts,
322328 typename = std::enable_if_t <
323329 (... and stdx::is_specialization_of_v<stdx::remove_cvref_t <Ts>,
324330 optional>)>>
331+ auto convert_optional (Ts const &...) -> optional<R>;
332+ template <typename R, typename ... Ts,
333+ typename = std::enable_if_t <
334+ (... and stdx::is_specialization_of_v<stdx::remove_cvref_t <Ts>,
335+ std::optional>)>>
336+ auto convert_optional (Ts const &...) -> std::optional<R>;
337+ } // namespace detail
338+
339+ template <typename F, typename ... Ts,
340+ typename = std::enable_if_t <(... and detail::optional_like<Ts>)>>
325341constexpr auto transform (F &&f, Ts &&...ts) {
326342 using func_t = stdx::remove_cvref_t <F>;
327343 using R = std::invoke_result_t <
328344 func_t ,
329345 forward_like_t <Ts, typename stdx::remove_cvref_t <Ts>::value_type>...>;
346+ using O = decltype (detail::convert_optional<R>(ts...));
330347 if ((... and ts.has_value ())) {
331- return optional<R> {with_result_of{[&] {
348+ return O {with_result_of{[&] {
332349 return std::forward<F>(f)(std::forward<Ts>(ts).value ()...);
333350 }}};
334351 }
335- return optional<R> {};
352+ return O {};
336353}
337354} // namespace v1
338355} // namespace stdx
0 commit comments