--- /dev/null
+/*
+ * Copyright 2015 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// included by Future.h, do not include directly.
+
+namespace folly {
+
+template <class> struct Promise;
+
+template <typename T>
+struct isFuture : std::false_type {
+ typedef T Inner;
+};
+
+template <typename T>
+struct isFuture<Future<T>> : std::true_type {
+ typedef T Inner;
+};
+
+template <typename T>
+struct isTry : std::false_type {};
+
+template <typename T>
+struct isTry<Try<T>> : std::true_type {};
+
+namespace detail {
+
+template <class> struct Core;
+template <class...> struct VariadicContext;
+template <class> struct CollectContext;
+
+template<typename F, typename... Args>
+using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
+
+template <typename...>
+struct ArgType;
+
+template <typename Arg, typename... Args>
+struct ArgType<Arg, Args...> {
+ typedef Arg FirstArg;
+};
+
+template <>
+struct ArgType<> {
+ typedef void FirstArg;
+};
+
+template <bool isTry, typename F, typename... Args>
+struct argResult {
+ typedef resultOf<F, Args...> Result;
+};
+
+template<typename F, typename... Args>
+struct callableWith {
+ template<typename T,
+ typename = detail::resultOf<T, Args...>>
+ static constexpr std::true_type
+ check(std::nullptr_t) { return std::true_type{}; };
+
+ template<typename>
+ static constexpr std::false_type
+ check(...) { return std::false_type{}; };
+
+ typedef decltype(check<F>(nullptr)) type;
+ static constexpr bool value = type::value;
+};
+
+template<typename T, typename F>
+struct callableResult {
+ typedef typename std::conditional<
+ callableWith<F>::value,
+ detail::argResult<false, F>,
+ typename std::conditional<
+ callableWith<F, T&&>::value,
+ detail::argResult<false, F, T&&>,
+ typename std::conditional<
+ callableWith<F, T&>::value,
+ detail::argResult<false, F, T&>,
+ typename std::conditional<
+ callableWith<F, Try<T>&&>::value,
+ detail::argResult<true, F, Try<T>&&>,
+ detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
+ typedef isFuture<typename Arg::Result> ReturnsFuture;
+ typedef Future<typename ReturnsFuture::Inner> Return;
+};
+
+template<typename F>
+struct callableResult<void, F> {
+ typedef typename std::conditional<
+ callableWith<F>::value,
+ detail::argResult<false, F>,
+ typename std::conditional<
+ callableWith<F, Try<void>&&>::value,
+ detail::argResult<true, F, Try<void>&&>,
+ detail::argResult<true, F, Try<void>&>>::type>::type Arg;
+ typedef isFuture<typename Arg::Result> ReturnsFuture;
+ typedef Future<typename ReturnsFuture::Inner> Return;
+};
+
+template <typename L>
+struct Extract : Extract<decltype(&L::operator())> { };
+
+template <typename Class, typename R, typename... Args>
+struct Extract<R(Class::*)(Args...) const> {
+ typedef isFuture<R> ReturnsFuture;
+ typedef Future<typename ReturnsFuture::Inner> Return;
+ typedef typename ReturnsFuture::Inner RawReturn;
+ typedef typename ArgType<Args...>::FirstArg FirstArg;
+};
+
+template <typename Class, typename R, typename... Args>
+struct Extract<R(Class::*)(Args...)> {
+ typedef isFuture<R> ReturnsFuture;
+ typedef Future<typename ReturnsFuture::Inner> Return;
+ typedef typename ReturnsFuture::Inner RawReturn;
+ typedef typename ArgType<Args...>::FirstArg FirstArg;
+};
+
+} // detail
+
+
+struct Timekeeper;
+
+} // namespace