AsyncSocket::writeRequest() and its first user wangle::FileRegion
[folly.git] / folly / wangle / channel / StaticPipeline.h
index 3c644eb747c97c8c35f95fa94fb69427fffff67e..a5d2e893eb5126d44a88fda999345390e195dbcb 100644 (file)
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <type_traits>
+
 #include <folly/wangle/channel/Pipeline.h>
 
 namespace folly { namespace wangle {
@@ -47,12 +49,25 @@ class StaticPipeline;
 template <class R, class W>
 class StaticPipeline<R, W> : public Pipeline<R, W> {
  protected:
-  explicit StaticPipeline(bool) : 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