folly: fix mismatched-tags
[folly.git] / folly / futures / Future-pre.h
1 /*
2  * Copyright 2015 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   typedef T Inner;
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 detail {
42
43 template <class> class Core;
44 template <class...> struct VariadicContext;
45 template <class> struct CollectContext;
46
47 template<typename F, typename... Args>
48 using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
49
50 template <typename...>
51 struct ArgType;
52
53 template <typename Arg, typename... Args>
54 struct ArgType<Arg, Args...> {
55   typedef Arg FirstArg;
56 };
57
58 template <>
59 struct ArgType<> {
60   typedef void FirstArg;
61 };
62
63 template <bool isTry, typename F, typename... Args>
64 struct argResult {
65   typedef resultOf<F, Args...> Result;
66 };
67
68 template<typename F, typename... Args>
69 struct callableWith {
70     template<typename T,
71              typename = detail::resultOf<T, Args...>>
72     static constexpr std::true_type
73     check(std::nullptr_t) { return std::true_type{}; };
74
75     template<typename>
76     static constexpr std::false_type
77     check(...) { return std::false_type{}; };
78
79     typedef decltype(check<F>(nullptr)) type;
80     static constexpr bool value = type::value;
81 };
82
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;
100 };
101
102 template<typename F>
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;
113 };
114
115 template <typename L>
116 struct Extract : Extract<decltype(&L::operator())> { };
117
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;
124 };
125
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;
132 };
133
134 } // detail
135
136
137 class Timekeeper;
138
139 } // namespace