Ensure getVia(eventbase) does not busy wait
[folly.git] / folly / futures / Future-pre.h
index f76c24abfd0a976a579d672e388239e3cfd3c113..2116ce8d11edbe57ac3757e3a6e43afbd85ddef0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ template <class> class Promise;
 
 template <typename T>
 struct isFuture : std::false_type {
-  typedef T Inner;
+  using Inner = typename Unit::Lift<T>::type;
 };
 
 template <typename T>
@@ -63,7 +63,7 @@ struct ArgType<> {
 
 template <bool isTry, typename F, typename... Args>
 struct argResult {
-  typedef resultOf<F, Args...> Result;
+  using Result = resultOf<F, Args...>;
 };
 
 template<typename F, typename... Args>
@@ -100,19 +100,6 @@ struct callableResult {
   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())> { };
 
@@ -132,8 +119,26 @@ struct Extract<R(Class::*)(Args...)> {
   typedef typename ArgType<Args...>::FirstArg FirstArg;
 };
 
-} // detail
+// 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 FunctionReferenceToPointer<R (&)(Args...)> {
+  using type = R (*)(Args...);
+};
 
+} // detail
 
 class Timekeeper;