AsyncSocket::writeRequest() and its first user wangle::FileRegion
[folly.git] / folly / wangle / channel / StaticPipeline.h
index 6c6c5e0868062269825052730f3513adb3b01c05..a5d2e893eb5126d44a88fda999345390e195dbcb 100644 (file)
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <type_traits>
+
 #include <folly/wangle/channel/Pipeline.h>
 
 namespace folly { namespace wangle {
@@ -50,9 +52,22 @@ class StaticPipeline<R, W> : public Pipeline<R, W> {
   explicit StaticPipeline(bool) : Pipeline<R, W>(true) {}
 };
 
+template <class Handler>
+class BaseWithOptional {
+ protected:
+  folly::Optional<Handler> handler_;
+};
+
+template <class Handler>
+class BaseWithoutOptional {
+};
+
 template <class R, class W, class Handler, class... Handlers>
 class StaticPipeline<R, W, Handler, Handlers...>
-    : public StaticPipeline<R, W, Handlers...> {
+    : public StaticPipeline<R, W, Handlers...>
+    , public std::conditional<std::is_abstract<Handler>::value,
+                              BaseWithoutOptional<Handler>,
+                              BaseWithOptional<Handler>>::type {
  public:
   template <class... HandlerArgs>
   explicit StaticPipeline(HandlerArgs&&... handlers)
@@ -67,8 +82,6 @@ class StaticPipeline<R, W, Handler, Handlers...>
   }
 
  protected:
-  typedef ContextImpl<Pipeline<R, W>, Handler> Context;
-
   template <class HandlerArg, class... HandlerArgs>
   StaticPipeline(
       bool isFirst,
@@ -94,8 +107,8 @@ class StaticPipeline<R, W, Handler, Handlers...>
     Handler
   >::value>::type
   setHandler(HandlerArg&& arg) {
-    handler_.emplace(std::forward<HandlerArg>(arg));
-    handlerPtr_ = std::shared_ptr<Handler>(&(*handler_), [](Handler*){});
+    BaseWithOptional<Handler>::handler_.emplace(std::forward<HandlerArg>(arg));
+    handlerPtr_ = std::shared_ptr<Handler>(&(*BaseWithOptional<Handler>::handler_), [](Handler*){});
   }
 
   template <class HandlerArg>
@@ -117,9 +130,8 @@ class StaticPipeline<R, W, Handler, Handlers...>
   }
 
   bool isFirst_;
-  folly::Optional<Handler> handler_;
   std::shared_ptr<Handler> handlerPtr_;
-  ContextImpl<Pipeline<R, W>, Handler> ctx_;
+  typename ContextType<Handler, Pipeline<R, W>>::type ctx_;
 };
 
 }} // folly::wangle