40fda3dcbcea30fc737933f1b19531ac06cc723a
[folly.git] / folly / fibers / Promise.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17
18 #include <folly/fibers/traits.h>
19 #include <folly/Try.h>
20
21 namespace folly {
22 namespace fibers {
23
24 class Baton;
25
26 template <typename T, typename BatonT = Baton>
27 class Promise {
28  public:
29   typedef T value_type;
30   typedef BatonT baton_type;
31
32   ~Promise();
33
34   // not copyable
35   Promise(const Promise&) = delete;
36   Promise& operator=(const Promise&) = delete;
37
38   // movable
39   Promise(Promise&&) noexcept;
40   Promise& operator=(Promise&&);
41
42   /** Fulfill this promise (only for Promise<void>) */
43   void setValue();
44
45   /** Set the value (use perfect forwarding for both move and copy) */
46   template <class M>
47   void setValue(M&& value);
48
49   /**
50    * Fulfill the promise with a given try
51    *
52    * @param t
53    */
54   void setTry(folly::Try<T>&& t);
55
56   /** Fulfill this promise with the result of a function that takes no
57     arguments and returns something implicitly convertible to T.
58     Captures exceptions. e.g.
59
60     p.setWith([] { do something that may throw; return a T; });
61   */
62   template <class F>
63   void setWith(F&& func);
64
65   /** Fulfill the Promise with an exception_wrapper, e.g.
66     auto ew = folly::try_and_catch<std::exception>([]{ ... });
67     if (ew) {
68       p.setException(std::move(ew));
69     }
70     */
71   void setException(folly::exception_wrapper);
72
73   /**
74    * Blocks task execution until given promise is fulfilled.
75    *
76    * Calls function passing in a Promise<T>, which has to be fulfilled.
77    *
78    * @return data which was used to fulfill the promise.
79    */
80   template <class F>
81   static value_type await(F&& func);
82
83  private:
84   Promise(folly::Try<T>& value, BatonT& baton);
85   folly::Try<T>* value_;
86   BatonT* baton_;
87
88   void throwIfFulfilled() const;
89
90   template <class F>
91   typename std::enable_if<
92       std::is_convertible<typename std::result_of<F()>::type, T>::value &&
93       !std::is_same<T, void>::value>::type
94   fulfilHelper(F&& func);
95
96   template <class F>
97   typename std::enable_if<
98       std::is_same<typename std::result_of<F()>::type, void>::value &&
99       std::is_same<T, void>::value>::type
100   fulfilHelper(F&& func);
101 };
102 }
103 }
104
105 #include <folly/fibers/Promise-inl.h>