• 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_PROMISE_H
16 #define GRPC_SRC_CORE_LIB_PROMISE_PROMISE_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <type_traits>
21 
22 #include "absl/functional/any_invocable.h"
23 #include "absl/status/status.h"
24 #include "absl/types/optional.h"
25 
26 #include "src/core/lib/promise/detail/promise_like.h"
27 #include "src/core/lib/promise/poll.h"
28 
29 namespace grpc_core {
30 
31 // A Promise is any functor that takes no arguments and returns Poll<T>.
32 // Most of the time we just pass around the functor, but occasionally
33 // it pays to have a type erased variant, which we define here.
34 template <typename T>
35 using Promise = absl::AnyInvocable<Poll<T>()>;
36 
37 // Helper to execute a promise immediately and return either the result or
38 // nothing.
39 template <typename Promise>
40 auto NowOrNever(Promise promise)
41     -> absl::optional<typename promise_detail::PromiseLike<Promise>::Result> {
42   auto r = promise_detail::PromiseLike<Promise>(std::move(promise))();
43   if (auto* p = r.value_if_ready()) {
44     return std::move(*p);
45   }
46   return {};
47 }
48 
49 // A promise that never completes.
50 template <typename T>
51 struct Never {
operatorNever52   Poll<T> operator()() { return Pending(); }
53 };
54 
55 namespace promise_detail {
56 // A promise that immediately completes.
57 template <typename T>
58 class Immediate {
59  public:
Immediate(T value)60   explicit Immediate(T value) : value_(std::move(value)) {}
61 
operator()62   Poll<T> operator()() { return std::move(value_); }
63 
64  private:
65   T value_;
66 };
67 }  // namespace promise_detail
68 
69 // Return \a value immediately
70 template <typename T>
Immediate(T value)71 promise_detail::Immediate<T> Immediate(T value) {
72   return promise_detail::Immediate<T>(std::move(value));
73 }
74 
75 // Return status Ok immediately
76 struct ImmediateOkStatus {
operatorImmediateOkStatus77   Poll<absl::Status> operator()() { return absl::OkStatus(); }
78 };
79 
80 // Typecheck that a promise returns the expected return type.
81 // usage: auto promise = WithResult<int>([]() { return 3; });
82 // NOTE: there are tests in promise_test.cc that are commented out because they
83 // should fail to compile. When modifying this code these should be uncommented
84 // and their miscompilation verified.
85 template <typename T, typename F>
86 auto WithResult(F f) ->
87     typename std::enable_if<std::is_same<decltype(f()), Poll<T>>::value,
88                             F>::type {
89   return f;
90 }
91 
92 template <typename Promise>
93 using PromiseResult = typename PollTraits<
94     typename promise_detail::PromiseLike<Promise>::Result>::Type;
95 
96 }  // namespace grpc_core
97 
98 #endif  // GRPC_SRC_CORE_LIB_PROMISE_PROMISE_H
99