template< -> template <
[folly.git] / folly / futures / Future-pre.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
17 #pragma once
18
19 // included by Future.h, do not include directly.
20
21 namespace folly {
22
23 template <class> class Promise;
24
25 template <typename T>
26 struct isFuture : std::false_type {
27   using Inner = typename Unit::Lift<T>::type;
28 };
29
30 template <typename T>
31 struct isFuture<Future<T>> : std::true_type {
32   typedef T Inner;
33 };
34
35 template <typename T>
36 struct isTry : std::false_type {};
37
38 template <typename T>
39 struct isTry<Try<T>> : std::true_type {};
40
41 namespace futures {
42 namespace detail {
43
44 template <class> class Core;
45 template <class...> struct CollectAllVariadicContext;
46 template <class...> struct CollectVariadicContext;
47 template <class> struct CollectContext;
48
49 template <typename F, typename... Args>
50 using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
51
52 template <typename...>
53 struct ArgType;
54
55 template <typename Arg, typename... Args>
56 struct ArgType<Arg, Args...> {
57   typedef Arg FirstArg;
58 };
59
60 template <>
61 struct ArgType<> {
62   typedef void FirstArg;
63 };
64
65 template <bool isTry, typename F, typename... Args>
66 struct argResult {
67   using Result = resultOf<F, Args...>;
68 };
69
70 template <typename F, typename... Args>
71 struct callableWith {
72     template <typename T, typename = detail::resultOf<T, Args...>>
73     static constexpr std::true_type
74     check(std::nullptr_t) { return std::true_type{}; }
75
76     template <typename>
77     static constexpr std::false_type
78     check(...) { return std::false_type{}; }
79
80     typedef decltype(check<F>(nullptr)) type;
81     static constexpr bool value = type::value;
82 };
83
84 template <typename T, typename F>
85 struct callableResult {
86   typedef typename std::conditional<
87     callableWith<F>::value,
88     detail::argResult<false, F>,
89     typename std::conditional<
90       callableWith<F, T&&>::value,
91       detail::argResult<false, F, T&&>,
92       typename std::conditional<
93         callableWith<F, T&>::value,
94         detail::argResult<false, F, T&>,
95         typename std::conditional<
96           callableWith<F, Try<T>&&>::value,
97           detail::argResult<true, F, Try<T>&&>,
98           detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
99   typedef isFuture<typename Arg::Result> ReturnsFuture;
100   typedef Future<typename ReturnsFuture::Inner> Return;
101 };
102
103 template <typename L>
104 struct Extract : Extract<decltype(&L::operator())> { };
105
106 template <typename Class, typename R, typename... Args>
107 struct Extract<R(Class::*)(Args...) const> {
108   typedef isFuture<R> ReturnsFuture;
109   typedef Future<typename ReturnsFuture::Inner> Return;
110   typedef typename ReturnsFuture::Inner RawReturn;
111   typedef typename ArgType<Args...>::FirstArg FirstArg;
112 };
113
114 template <typename Class, typename R, typename... Args>
115 struct Extract<R(Class::*)(Args...)> {
116   typedef isFuture<R> ReturnsFuture;
117   typedef Future<typename ReturnsFuture::Inner> Return;
118   typedef typename ReturnsFuture::Inner RawReturn;
119   typedef typename ArgType<Args...>::FirstArg FirstArg;
120 };
121
122 template <typename R, typename... Args>
123 struct Extract<R (*)(Args...)> {
124   typedef isFuture<R> ReturnsFuture;
125   typedef Future<typename ReturnsFuture::Inner> Return;
126   typedef typename ReturnsFuture::Inner RawReturn;
127   typedef typename ArgType<Args...>::FirstArg FirstArg;
128 };
129
130 template <typename R, typename... Args>
131 struct Extract<R (&)(Args...)> {
132   typedef isFuture<R> ReturnsFuture;
133   typedef Future<typename ReturnsFuture::Inner> Return;
134   typedef typename ReturnsFuture::Inner RawReturn;
135   typedef typename ArgType<Args...>::FirstArg FirstArg;
136 };
137
138 } // namespace detail
139 } // namespace futures
140
141 class Timekeeper;
142
143 } // namespace