1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef GRPC_SRC_CORE_LIB_PROMISE_ALL_OK_H
16 #define GRPC_SRC_CORE_LIB_PROMISE_ALL_OK_H
17
18 #include <grpc/support/port_platform.h>
19
20 #include <tuple>
21 #include <variant>
22
23 #include "absl/meta/type_traits.h"
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26
27 #include "src/core/lib/promise/detail/join_state.h"
28 #include "src/core/lib/promise/map.h"
29 #include "src/core/lib/promise/poll.h"
30 #include "src/core/lib/promise/status_flag.h"
31
32 namespace grpc_core {
33
34 namespace promise_detail {
35
36 // Traits object to pass to JoinState
37 template <typename Result>
38 struct AllOkTraits {
39 template <typename T>
40 using ResultType = Result;
41 template <typename T>
IsOkAllOkTraits42 static bool IsOk(const T& x) {
43 return IsStatusOk(x);
44 }
UnwrappedAllOkTraits45 static Empty Unwrapped(StatusFlag) { return Empty{}; }
UnwrappedAllOkTraits46 static Empty Unwrapped(absl::Status) { return Empty{}; }
47 template <typename R, typename T>
EarlyReturnAllOkTraits48 static R EarlyReturn(T&& x) {
49 return StatusCast<R>(std::forward<T>(x));
50 }
51 template <typename... A>
FinalReturnAllOkTraits52 static Result FinalReturn(A&&...) {
53 return Result{};
54 }
55 };
56
57 // Implementation of AllOk combinator.
58 template <typename Result, typename... Promises>
59 class AllOk {
60 public:
AllOk(Promises...promises)61 explicit AllOk(Promises... promises) : state_(std::move(promises)...) {}
operator()62 auto operator()() { return state_.PollOnce(); }
63
64 private:
65 JoinState<AllOkTraits<Result>, Promises...> state_;
66 };
67
68 } // namespace promise_detail
69
70 // Run all promises.
71 // If any fail, cancel the rest and return the failure.
72 // If all succeed, return Ok.
73 template <typename Result, typename... Promises>
AllOk(Promises...promises)74 auto AllOk(Promises... promises) {
75 return promise_detail::AllOk<Result, Promises...>(std::move(promises)...);
76 }
77
78 } // namespace grpc_core
79
80 #endif // GRPC_SRC_CORE_LIB_PROMISE_ALL_OK_H
81