@@ -131,7 +131,7 @@ class Result {
131131 * expressions, as fold expressions significantly complicates error messages
132132 *
133133 * constraints:
134- * - Callable must be invocable with at least one error type as an argument
134+ * - Callable must be invocable with all error types as arguments
135135 * - If invocable, the callable must always return the same type regardless of argument type
136136 * - If invocable, the callable must return a Result
137137 * - The Result returned by the callable must have the same value type
@@ -142,53 +142,29 @@ class Result {
142142 * @param f the callable
143143 */
144144 template <typename Self, typename F>
145- requires traits::AnyInvocable <Self, F, Errs...>
145+ requires traits::AllInvocable <Self, F, Errs...>
146146 // the callable must always return the same type (if it's invocable)
147147 && traits::AllSame<traits::or_else_return_t <Self, F, Errs>...>
148148 // the callable must return a Result (if it's invocable)
149149 && traits::AllResult<Self, F, Errs...>
150150 // the Result returned by the callable must have the same value type
151151 && traits::AllValueTypeMatch<Self, traits::or_else_return_t <Self, F, Errs>...>
152152 constexpr auto or_else (this Self&& self, F&& f) {
153- using namespace traits ;
154-
155- // the return type is the same as the return type of the callable, unless the callable
156- // returns void. In that case, the return type is Self with cv-refs removed
157- using CallableReturnType =
158- first_type_that_satisfies_t <invocable_indirect_v<F, Self>, Errs...>;
159- using ReturnType = std::conditional_t <
160- IsResult<CallableReturnType>,
161- CallableReturnType,
162- std::remove_cvref_t <Self>>;
153+ using ReturnType = std::invoke_result_t <
154+ F,
155+ decltype ((std::get<std::tuple_element_t <0 , std::tuple<Errs...>>>(std::declval<Self>()
156+ .error )))>;
163157
164158 // if there isn't an error, return the value
165159 if (!self.has_error ()) {
166160 return ReturnType (std::forward<Self>(self).value );
167161 }
168162
169- // if the callable returns void
170- if constexpr (std::same_as<void , CallableReturnType>) {
171- return std::visit ([&f](auto && arg) -> ReturnType {
172- // even though this condition is impossible, it's necessary. Otherwise the
173- // compiler will compile a branch where f is invoked with an unsupported argument
174- // type
175- if constexpr (!Invocable<Self, F, decltype ((arg))>
176- || std::same_as<std::monostate, std::remove_cvref_t <decltype (arg)>>) {
177- throw std::logic_error (" This exception is unreachable" );
178- } else {
179- std::invoke (f, std::forward<decltype (arg)>(arg));
180- return std::forward<decltype (arg)>(arg);
181- }
182- }, std::forward<Self>(self).error );
183- }
184-
185- // if the callable returns Result
186163 return std::visit ([&f](auto && arg) -> ReturnType {
187164 // even though this condition is impossible, it's necessary. Otherwise the
188165 // compiler will compile a branch where f is invoked with an unsupported argument
189166 // type
190- if constexpr (!Invocable<Self, F, decltype ((arg))>
191- || std::same_as<std::monostate, std::remove_cvref_t <decltype (arg)>>) {
167+ if constexpr (std::same_as<std::monostate, std::remove_cvref_t <decltype (arg)>>) {
192168 throw std::logic_error (" This exception is unreachable" );
193169 } else {
194170 std::invoke (f, std::forward<decltype (arg)>(arg));
@@ -331,7 +307,7 @@ class Result<void, Errs...> {
331307 * expressions, as fold expressions significantly complicates error messages
332308 *
333309 * constraints:
334- * - Callable must be invocable with at least one error type as an argument
310+ * - Callable must be invocable with any error type as an argument
335311 * - If invocable, the callable must always return the same type regardless of argument type
336312 * - If invocable, the callable must return a Result
337313 * - The Result returned by the callable must have the same value type
@@ -342,53 +318,28 @@ class Result<void, Errs...> {
342318 * @param f the callable
343319 */
344320 template <typename Self, typename F>
345- requires traits::AnyInvocable <Self, F, Errs...>
321+ requires traits::AllInvocable <Self, F, Errs...>
346322 // the callable must always return the same type (if it's invocable)
347323 && traits::AllSame<traits::or_else_return_t <Self, F, Errs>...>
348324 // the callable must return a Result (if it's invocable)
349325 && traits::AllResult<Self, F, Errs...>
350326 // the Result returned by the callable must have the same value type
351327 && traits::AllValueTypeMatch<Self, traits::or_else_return_t <Self, F, Errs>...>
352328 constexpr auto or_else (this Self&& self, F&& f) {
353- using namespace traits ;
354-
355- // the return type is the same as the return type of the callable, unless the callable
356- // returns void. In that case, the return type is Self with cv-refs removed
357- using CallableReturnType =
358- first_type_that_satisfies_t <invocable_indirect_v<F, Self>, Errs...>;
359- using ReturnType = std::conditional_t <
360- IsResult<CallableReturnType>,
361- CallableReturnType,
362- std::remove_cvref_t <Self>>;
363-
329+ using ReturnType = std::invoke_result_t <
330+ F,
331+ decltype ((std::get<std::tuple_element_t <0 , std::tuple<Errs...>>>(std::declval<Self>()
332+ .error )))>;
364333 // if there isn't an error, return
365334 if (!self.has_error ()) {
366335 return ReturnType ();
367336 }
368337
369- // if the callable returns void
370- if constexpr (std::same_as<void , CallableReturnType>) {
371- return std::visit ([&f](auto && arg) -> ReturnType {
372- // even though this condition is impossible, it's necessary. Otherwise the
373- // compiler will compile a branch where f is invoked with an unsupported argument
374- // type
375- if constexpr (!Invocable<Self, F, decltype ((arg))>
376- || std::same_as<std::monostate, std::remove_cvref_t <decltype (arg)>>) {
377- throw std::logic_error (" This exception is unreachable" );
378- } else {
379- std::invoke (f, std::forward<decltype (arg)>(arg));
380- return std::forward<decltype (arg)>(arg);
381- }
382- }, std::forward<Self>(self).error );
383- }
384-
385- // if the callable returns Result
386338 return std::visit ([&f](auto && arg) -> ReturnType {
387339 // even though this condition is impossible, it's necessary. Otherwise the
388340 // compiler will compile a branch where f is invoked with an unsupported argument
389341 // type
390- if constexpr (!Invocable<Self, F, decltype ((arg))>
391- || std::same_as<std::monostate, std::remove_cvref_t <decltype (arg)>>) {
342+ if constexpr (std::same_as<std::monostate, std::remove_cvref_t <decltype (arg)>>) {
392343 throw std::logic_error (" This exception is unreachable" );
393344 } else {
394345 std::invoke (f, std::forward<decltype (arg)>(arg));
0 commit comments