2 * Copyright 2015 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 // included by Future.h, do not include directly.
23 template <class> class Promise;
26 struct isFuture : std::false_type {
31 struct isFuture<Future<T>> : std::true_type {
36 struct isTry : std::false_type {};
39 struct isTry<Try<T>> : std::true_type {};
43 template <class> class Core;
44 template <class...> struct VariadicContext;
45 template <class> struct CollectContext;
47 template<typename F, typename... Args>
48 using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
50 template <typename...>
53 template <typename Arg, typename... Args>
54 struct ArgType<Arg, Args...> {
60 typedef void FirstArg;
63 template <bool isTry, typename F, typename... Args>
65 typedef resultOf<F, Args...> Result;
68 template<typename F, typename... Args>
71 typename = detail::resultOf<T, Args...>>
72 static constexpr std::true_type
73 check(std::nullptr_t) { return std::true_type{}; };
76 static constexpr std::false_type
77 check(...) { return std::false_type{}; };
79 typedef decltype(check<F>(nullptr)) type;
80 static constexpr bool value = type::value;
83 template<typename T, typename F>
84 struct callableResult {
85 typedef typename std::conditional<
86 callableWith<F>::value,
87 detail::argResult<false, F>,
88 typename std::conditional<
89 callableWith<F, T&&>::value,
90 detail::argResult<false, F, T&&>,
91 typename std::conditional<
92 callableWith<F, T&>::value,
93 detail::argResult<false, F, T&>,
94 typename std::conditional<
95 callableWith<F, Try<T>&&>::value,
96 detail::argResult<true, F, Try<T>&&>,
97 detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
98 typedef isFuture<typename Arg::Result> ReturnsFuture;
99 typedef Future<typename ReturnsFuture::Inner> Return;
103 struct callableResult<void, F> {
104 typedef typename std::conditional<
105 callableWith<F>::value,
106 detail::argResult<false, F>,
107 typename std::conditional<
108 callableWith<F, Try<void>&&>::value,
109 detail::argResult<true, F, Try<void>&&>,
110 detail::argResult<true, F, Try<void>&>>::type>::type Arg;
111 typedef isFuture<typename Arg::Result> ReturnsFuture;
112 typedef Future<typename ReturnsFuture::Inner> Return;
115 template <typename L>
116 struct Extract : Extract<decltype(&L::operator())> { };
118 template <typename Class, typename R, typename... Args>
119 struct Extract<R(Class::*)(Args...) const> {
120 typedef isFuture<R> ReturnsFuture;
121 typedef Future<typename ReturnsFuture::Inner> Return;
122 typedef typename ReturnsFuture::Inner RawReturn;
123 typedef typename ArgType<Args...>::FirstArg FirstArg;
126 template <typename Class, typename R, typename... Args>
127 struct Extract<R(Class::*)(Args...)> {
128 typedef isFuture<R> ReturnsFuture;
129 typedef Future<typename ReturnsFuture::Inner> Return;
130 typedef typename ReturnsFuture::Inner RawReturn;
131 typedef typename ArgType<Args...>::FirstArg FirstArg;