template< -> template <
[folly.git] / folly / futures / Future-pre.h
index a6f77b44f74797b29f3e10798409bcf87f47792f..8d1fd98f04940bf3de21bc2b199e62b9fa031907 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ struct isTry : std::false_type {};
 template <typename T>
 struct isTry<Try<T>> : std::true_type {};
 
+namespace futures {
 namespace detail {
 
 template <class> class Core;
@@ -45,7 +46,7 @@ template <class...> struct CollectAllVariadicContext;
 template <class...> struct CollectVariadicContext;
 template <class> struct CollectContext;
 
-template<typename F, typename... Args>
+template <typename F, typename... Args>
 using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
 
 template <typename...>
@@ -66,14 +67,13 @@ struct argResult {
   using Result = resultOf<F, Args...>;
 };
 
-template<typename F, typename... Args>
+template <typename F, typename... Args>
 struct callableWith {
-    template<typename T,
-             typename = detail::resultOf<T, Args...>>
+    template <typename T, typename = detail::resultOf<T, Args...>>
     static constexpr std::true_type
     check(std::nullptr_t) { return std::true_type{}; }
 
-    template<typename>
+    template <typename>
     static constexpr std::false_type
     check(...) { return std::false_type{}; }
 
@@ -81,7 +81,7 @@ struct callableWith {
     static constexpr bool value = type::value;
 };
 
-template<typename T, typename F>
+template <typename T, typename F>
 struct callableResult {
   typedef typename std::conditional<
     callableWith<F>::value,
@@ -119,26 +119,24 @@ struct Extract<R(Class::*)(Args...)> {
   typedef typename ArgType<Args...>::FirstArg FirstArg;
 };
 
-// gcc-4.8 refuses to capture a function reference in a lambda. This can be
-// mitigated by casting them to function pointer types first. The following
-// helper is used in Future.h to achieve that where necessary.
-// When compiling with gcc versions 4.9 and up, as well as clang, we do not
-// need to apply FunctionReferenceToPointer (i.e. T can be used instead of
-// FunctionReferenceToPointer<T>).
-// Applying FunctionReferenceToPointer first, the code works on all tested
-// compiler versions: gcc 4.8 and above, cland 3.5 and above.
-
-template <typename T>
-struct FunctionReferenceToPointer {
-  using type = T;
+template <typename R, typename... Args>
+struct Extract<R (*)(Args...)> {
+  typedef isFuture<R> ReturnsFuture;
+  typedef Future<typename ReturnsFuture::Inner> Return;
+  typedef typename ReturnsFuture::Inner RawReturn;
+  typedef typename ArgType<Args...>::FirstArg FirstArg;
 };
 
 template <typename R, typename... Args>
-struct FunctionReferenceToPointer<R (&)(Args...)> {
-  using type = R (*)(Args...);
+struct Extract<R (&)(Args...)> {
+  typedef isFuture<R> ReturnsFuture;
+  typedef Future<typename ReturnsFuture::Inner> Return;
+  typedef typename ReturnsFuture::Inner RawReturn;
+  typedef typename ArgType<Args...>::FirstArg FirstArg;
 };
 
-} // detail
+} // namespace detail
+} // namespace futures
 
 class Timekeeper;