1/*
2 * Copyright 2015-present 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// included by Future.h, do not include directly.
19
20namespace folly {
21
22template <class>
23class Promise;
24
25template <class T>
26class SemiFuture;
27
28template <typename T>
29struct isSemiFuture : std::false_type {
30 using Inner = lift_unit_t<T>;
31};
32
33template <typename T>
34struct isSemiFuture<SemiFuture<T>> : std::true_type {
35 typedef T Inner;
36};
37
38template <typename T>
39struct isFuture : std::false_type {
40 using Inner = lift_unit_t<T>;
41};
42
43template <typename T>
44struct isFuture<Future<T>> : std::true_type {
45 typedef T Inner;
46};
47
48template <typename T>
49struct isFutureOrSemiFuture : std::false_type {
50 using Inner = lift_unit_t<T>;
51 using Return = Inner;
52};
53
54template <typename T>
55struct isFutureOrSemiFuture<Future<T>> : std::true_type {
56 typedef T Inner;
57 using Return = Future<Inner>;
58};
59
60template <typename T>
61struct isFutureOrSemiFuture<SemiFuture<T>> : std::true_type {
62 typedef T Inner;
63 using Return = SemiFuture<Inner>;
64};
65
66template <typename T>
67struct isTry : std::false_type {};
68
69template <typename T>
70struct isTry<Try<T>> : std::true_type {};
71
72namespace futures {
73namespace detail {
74
75template <class>
76class Core;
77
78template <typename...>
79struct ArgType;
80
81template <typename Arg, typename... Args>
82struct ArgType<Arg, Args...> {
83 typedef Arg FirstArg;
84};
85
86template <>
87struct ArgType<> {
88 typedef void FirstArg;
89};
90
91template <bool isTry_, typename F, typename... Args>
92struct argResult {
93 using Function = F;
94 using ArgList = ArgType<Args...>;
95 using Result = invoke_result_t<F, Args...>;
96 using ArgsSize = index_constant<sizeof...(Args)>;
97 static constexpr bool isTry() {
98 return isTry_;
99 }
100};
101
102template <typename T, typename F>
103struct callableResult {
104 typedef typename std::conditional<
105 is_invocable<F>::value,
106 detail::argResult<false, F>,
107 typename std::conditional<
108 is_invocable<F, T&&>::value,
109 detail::argResult<false, F, T&&>,
110 detail::argResult<true, F, Try<T>&&>>::type>::type Arg;
111 typedef isFutureOrSemiFuture<typename Arg::Result> ReturnsFuture;
112 typedef Future<typename ReturnsFuture::Inner> Return;
113};
114
115template <
116 typename T,
117 typename F,
118 typename = std::enable_if_t<is_invocable<F, Try<T>&&>::value>>
119struct tryCallableResult {
120 typedef detail::argResult<true, F, Try<T>&&> Arg;
121 typedef isFutureOrSemiFuture<typename Arg::Result> ReturnsFuture;
122 typedef typename ReturnsFuture::Inner value_type;
123 typedef Future<value_type> Return;
124};
125
126template <
127 typename T,
128 typename F,
129 typename = std::enable_if_t<is_invocable<F, Executor*, Try<T>&&>::value>>
130struct tryExecutorCallableResult {
131 typedef detail::argResult<true, F, Executor*, Try<T>&&> Arg;
132 typedef isFutureOrSemiFuture<typename Arg::Result> ReturnsFuture;
133 typedef typename ReturnsFuture::Inner value_type;
134 typedef Future<value_type> Return;
135};
136
137template <typename T, typename F>
138struct valueCallableResult {
139 typedef detail::argResult<false, F, T&&> Arg;
140 typedef isFutureOrSemiFuture<typename Arg::Result> ReturnsFuture;
141 typedef typename ReturnsFuture::Inner value_type;
142 typedef typename Arg::ArgList::FirstArg FirstArg;
143 typedef Future<value_type> Return;
144};
145
146template <typename L>
147struct Extract : Extract<decltype(&L::operator())> {};
148
149template <typename Class, typename R, typename... Args>
150struct Extract<R (Class::*)(Args...) const> {
151 typedef isFutureOrSemiFuture<R> ReturnsFuture;
152 typedef Future<typename ReturnsFuture::Inner> Return;
153 typedef typename ReturnsFuture::Inner RawReturn;
154 typedef typename ArgType<Args...>::FirstArg FirstArg;
155};
156
157template <typename Class, typename R, typename... Args>
158struct Extract<R (Class::*)(Args...)> {
159 typedef isFutureOrSemiFuture<R> ReturnsFuture;
160 typedef Future<typename ReturnsFuture::Inner> Return;
161 typedef typename ReturnsFuture::Inner RawReturn;
162 typedef typename ArgType<Args...>::FirstArg FirstArg;
163};
164
165template <typename R, typename... Args>
166struct Extract<R (*)(Args...)> {
167 typedef isFutureOrSemiFuture<R> ReturnsFuture;
168 typedef Future<typename ReturnsFuture::Inner> Return;
169 typedef typename ReturnsFuture::Inner RawReturn;
170 typedef typename ArgType<Args...>::FirstArg FirstArg;
171};
172
173template <typename R, typename... Args>
174struct Extract<R (&)(Args...)> {
175 typedef isFutureOrSemiFuture<R> ReturnsFuture;
176 typedef Future<typename ReturnsFuture::Inner> Return;
177 typedef typename ReturnsFuture::Inner RawReturn;
178 typedef typename ArgType<Args...>::FirstArg FirstArg;
179};
180
181class DeferredExecutor;
182
183} // namespace detail
184} // namespace futures
185
186class Timekeeper;
187
188} // namespace folly
189