rearrange Future.h
[folly.git] / folly / futures / Future-pre.h
diff --git a/folly/futures/Future-pre.h b/folly/futures/Future-pre.h
new file mode 100644 (file)
index 0000000..70add42
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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