• 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_RACE_H
16 #define GRPC_SRC_CORE_LIB_PROMISE_RACE_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <utility>
21 
22 namespace grpc_core {
23 
24 namespace promise_detail {
25 
26 // Implementation type for Race combinator.
27 template <typename... Promises>
28 class Race;
29 
30 template <typename Promise, typename... Promises>
31 class Race<Promise, Promises...> {
32  public:
33   using Result = decltype(std::declval<Promise>()());
34 
Race(Promise promise,Promises...promises)35   explicit Race(Promise promise, Promises... promises)
36       : promise_(std::move(promise)), next_(std::move(promises)...) {}
37 
operator()38   Result operator()() {
39     // Check our own promise.
40     auto r = promise_();
41     if (r.pending()) {
42       // Check the rest of them.
43       return next_();
44     }
45     // Return the first ready result.
46     return std::move(r.value());
47   }
48 
49  private:
50   // The Promise checked by this instance.
51   Promise promise_;
52   // We recursively expand to check the rest of the instances.
53   Race<Promises...> next_;
54 };
55 
56 template <typename Promise>
57 class Race<Promise> {
58  public:
59   using Result = decltype(std::declval<Promise>()());
Race(Promise promise)60   explicit Race(Promise promise) : promise_(std::move(promise)) {}
operator()61   Result operator()() { return promise_(); }
62 
63  private:
64   Promise promise_;
65 };
66 
67 }  // namespace promise_detail
68 
69 /// Run all the promises, return the first result that's available.
70 /// If two results are simultaneously available, bias towards the first result
71 /// listed.
72 template <typename... Promises>
Race(Promises...promises)73 promise_detail::Race<Promises...> Race(Promises... promises) {
74   return promise_detail::Race<Promises...>(std::move(promises)...);
75 }
76 
77 }  // namespace grpc_core
78 
79 #endif  // GRPC_SRC_CORE_LIB_PROMISE_RACE_H
80