logging: reduce the amount of code emitted for log statements
[folly.git] / folly / Partial.h
index f19941fbf19f514d3a91372c626f2c6f38fc6e36..b39145287cf7eab928c00a18bf99ec5a0d42fb67 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.
 
 namespace folly {
 
+namespace detail {
+namespace partial {
+
+// helper type to make sure that the templated constructor in Partial does
+// not accidentally act as copy or move constructor
+struct PartialConstructFromCallable {};
+
 template <typename F, typename Tuple>
 class Partial {
  private:
@@ -28,12 +35,15 @@ class Partial {
 
  public:
   template <typename Callable, typename... Args>
-  Partial(Callable&& callable, Args&&... args)
+  Partial(PartialConstructFromCallable, Callable&& callable, Args&&... args)
       : f_(std::forward<Callable>(callable)),
         stored_args_(std::forward<Args>(args)...) {}
 
   template <typename... CArgs>
-  auto operator()(CArgs&&... cargs) & {
+  auto operator()(CArgs&&... cargs) & -> decltype(applyTuple(
+      static_cast<F&>(f_),
+      static_cast<Tuple&>(stored_args_),
+      std::forward_as_tuple(std::forward<CArgs>(cargs)...))) {
     return applyTuple(
         static_cast<F&>(f_),
         static_cast<Tuple&>(stored_args_),
@@ -41,7 +51,10 @@ class Partial {
   }
 
   template <typename... CArgs>
-  auto operator()(CArgs&&... cargs) const& {
+  auto operator()(CArgs&&... cargs) const& -> decltype(applyTuple(
+      static_cast<F const&>(f_),
+      static_cast<Tuple const&>(stored_args_),
+      std::forward_as_tuple(std::forward<CArgs>(cargs)...))) {
     return applyTuple(
         static_cast<F const&>(f_),
         static_cast<Tuple const&>(stored_args_),
@@ -49,7 +62,10 @@ class Partial {
   }
 
   template <typename... CArgs>
-  auto operator()(CArgs&&... cargs) && {
+  auto operator()(CArgs&&... cargs) && -> decltype(applyTuple(
+      static_cast<F&&>(f_),
+      static_cast<Tuple&&>(stored_args_),
+      std::forward_as_tuple(std::forward<CArgs>(cargs)...))) {
     return applyTuple(
         static_cast<F&&>(f_),
         static_cast<Tuple&&>(stored_args_),
@@ -57,6 +73,9 @@ class Partial {
   }
 };
 
+} // namespace partial
+} // namespace detail
+
 /**
  * Partially applies arguments to a callable
  *
@@ -80,10 +99,12 @@ class Partial {
  * and passed to the original callable.
  */
 template <typename F, typename... Args>
-auto partial(F&& f, Args&&... args) -> Partial<
+auto partial(F&& f, Args&&... args) -> detail::partial::Partial<
     typename std::decay<F>::type,
     std::tuple<typename std::decay<Args>::type...>> {
-  return {std::forward<F>(f), std::forward<Args>(args)...};
+  return {detail::partial::PartialConstructFromCallable{},
+          std::forward<F>(f),
+          std::forward<Args>(args)...};
 }
 
 } // namespace folly