• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_JOIN_H
16 #define GRPC_SRC_CORE_LIB_PROMISE_JOIN_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <stdlib.h>
21 
22 #include <tuple>
23 
24 #include "absl/meta/type_traits.h"
25 
26 #include "src/core/lib/promise/detail/join_state.h"
27 #include "src/core/lib/promise/map.h"
28 
29 namespace grpc_core {
30 namespace promise_detail {
31 
32 struct JoinTraits {
33   template <typename T>
34   using ResultType = absl::remove_reference_t<T>;
35   template <typename T>
IsOkJoinTraits36   static bool IsOk(const T&) {
37     return true;
38   }
39   template <typename T>
UnwrappedJoinTraits40   static T Unwrapped(T x) {
41     return x;
42   }
43   template <typename R, typename T>
EarlyReturnJoinTraits44   static R EarlyReturn(T) {
45     abort();
46   }
47   template <typename... A>
FinalReturnJoinTraits48   static std::tuple<A...> FinalReturn(A... a) {
49     return std::make_tuple(std::move(a)...);
50   }
51 };
52 
53 template <typename... Promises>
54 class Join {
55  public:
Join(Promises...promises)56   explicit Join(Promises... promises) : state_(std::move(promises)...) {}
operator()57   auto operator()() { return state_.PollOnce(); }
58 
59  private:
60   JoinState<JoinTraits, Promises...> state_;
61 };
62 
63 struct WrapInTuple {
64   template <typename T>
operatorWrapInTuple65   std::tuple<T> operator()(T x) {
66     return std::make_tuple(std::move(x));
67   }
68 };
69 
70 }  // namespace promise_detail
71 
72 /// Combinator to run all promises to completion, and return a tuple
73 /// of their results.
74 template <typename... Promise>
Join(Promise...promises)75 promise_detail::Join<Promise...> Join(Promise... promises) {
76   return promise_detail::Join<Promise...>(std::move(promises)...);
77 }
78 
79 template <typename F>
Join(F promise)80 auto Join(F promise) {
81   return Map(std::move(promise), promise_detail::WrapInTuple{});
82 }
83 
84 }  // namespace grpc_core
85 
86 #endif  // GRPC_SRC_CORE_LIB_PROMISE_JOIN_H
87