@@ -63,33 +63,20 @@ constexpr auto invoke(F&& f, Args&&... args)
6363 static_cast <F&&>(f), static_cast <Args&&>(args)...);
6464}
6565
66- template <class T >
67- void implicit_cast (T) noexcept ;
68-
6966template <class R , class F , class ... Args,
70- class = std::enable_if_t <!std::is_void_v<R>>,
71- class = decltype ((implicit_cast<R>)(
72- invoke_impl<std::decay_t <F>>::call(
73- std::declval<F>(), std::declval<Args>()...)))
67+ class E = decltype (invoke_impl<std::decay_t <F>>::call(
68+ std::declval<F>(), std::declval<Args>()...)),
69+ class = std::enable_if_t <std::is_void_v<R> || std::is_convertible_v<E,R>>
7470>
7571constexpr R invoke (F&& f, Args&&... args)
76- noexcept (noexcept ((implicit_cast<R>)(
77- invoke_impl<std::decay_t <F>>::call(
78- static_cast <F&&>(f), static_cast<Args&&>(args)...))))
79- {
80- return invoke_impl<std::decay_t <F>>::call (
81- static_cast <F&&>(f), static_cast <Args&&>(args)...);
82- }
83-
84- template <class R , class F , class ... Args,
85- class = std::enable_if_t <std::is_void_v<R>>,
86- class = decltype (invoke_impl<std::decay_t <F>>::call(
87- std::declval<F>(), std::declval<Args>()...))
88- >
89- constexpr void invoke (F&& f, Args&&... args)
9072 noexcept (noexcept (invoke_impl<std::decay_t <F>>::call(
91- static_cast <F&&>(f), static_cast<Args&&>(args)...)))
73+ static_cast <F&&>(f), static_cast<Args&&>(args)...)) &&
74+ (std::is_void_v<R> || std::is_nothrow_convertible_v<E,R>))
9275{
93- invoke_impl<std::decay_t <F>>::call (
94- static_cast <F&&>(f), static_cast <Args&&>(args)...);
76+ if constexpr (!std::is_void_v<R>)
77+ return invoke_impl<std::decay_t <F>>::call (
78+ static_cast <F&&>(f), static_cast <Args&&>(args)...);
79+ else
80+ invoke_impl<std::decay_t <F>>::call (
81+ static_cast <F&&>(f), static_cast <Args&&>(args)...);
9582}
0 commit comments