Don't try and instantiate an invalid function in DiscriminatedPtrDetail
authorChristopher Dykes <cdykes@fb.com>
Fri, 1 Jul 2016 01:09:29 +0000 (18:09 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Fri, 1 Jul 2016 01:24:13 +0000 (18:24 -0700)
Summary:
THe issue is quite simple: Regardless of the control flow, the previous implementation of this was instantiating `ApplyVisitor1<V,R>` which declares a return type, but never returns.
This refactors `ApplyVisitor1` and `ApplyConstVisitor1` so that the part of the control flow that was previously never reached simply doesn't exist anymore.

Reviewed By: yfeldblum

Differential Revision: D3479584

fbshipit-source-id: 605a48e39bba6dc14df1af1e76b55ea60f3e69d5

folly/detail/DiscriminatedPtrDetail.h

index 8795321ab4eb65645eb7879789a9c917db9d5cef..c87c9b4b322ebf5014e62c4e1c5ea118969e2b67 100644 (file)
@@ -110,53 +110,59 @@ struct ConstVisitorResult {
     typename ConstVisitorResult1<V,Types>::type...>::type type;
 };
 
-template <typename V, typename R, typename... Types> struct ApplyVisitor1;
+template <size_t index, typename V, typename R, typename... Types>
+struct ApplyVisitor1;
 
-template <typename V, typename R>
-struct ApplyVisitor1<V, R> {
-  R operator()(size_t /* index */, V&& /* visitor */, void* /* ptr */) const {
-    CHECK(false);  // NOTREACHED
+template <typename V, typename R, typename T, typename... Types>
+struct ApplyVisitor1<1, V, R, T, Types...> {
+  R operator()(size_t, V&& visitor, void* ptr) const {
+    return visitor(static_cast<T*>(ptr));
   }
 };
 
-template <typename V, typename R, typename T, typename... Types>
-struct ApplyVisitor1<V, R, T, Types...> {
-  R operator()(size_t index, V&& visitor, void* ptr) const {
-    return (index == 1 ? visitor(static_cast<T*>(ptr)) :
-            ApplyVisitor1<V, R, Types...>()(
-              index - 1, std::forward<V>(visitor), ptr));
+template <size_t index, typename V, typename R, typename T, typename... Types>
+struct ApplyVisitor1<index, V, R, T, Types...> {
+  R operator()(size_t runtimeIndex, V&& visitor, void* ptr) const {
+    return runtimeIndex == 1
+        ? visitor(static_cast<T*>(ptr))
+        : ApplyVisitor1<index - 1, V, R, Types...>()(
+              runtimeIndex - 1, std::forward<V>(visitor), ptr);
   }
 };
 
-template <typename V, typename R, typename... Types> struct ApplyConstVisitor1;
+template <size_t index, typename V, typename R, typename... Types>
+struct ApplyConstVisitor1;
 
-template <typename V, typename R>
-struct ApplyConstVisitor1<V, R> {
-  R operator()(size_t /* index */, V&& /* visitor */, void* /* ptr */) const {
-    CHECK(false);  // NOTREACHED
+template <typename V, typename R, typename T, typename... Types>
+struct ApplyConstVisitor1<1, V, R, T, Types...> {
+  R operator()(size_t, V&& visitor, void* ptr) const {
+    return visitor(static_cast<const T*>(ptr));
   }
 };
 
-template <typename V, typename R, typename T, typename... Types>
-struct ApplyConstVisitor1<V, R, T, Types...> {
-  R operator()(size_t index, V&& visitor, void* ptr) const {
-    return (index == 1 ? visitor(static_cast<const T*>(ptr)) :
-            ApplyConstVisitor1<V, R, Types...>()(
-              index - 1, std::forward<V>(visitor), ptr));
+template <size_t index, typename V, typename R, typename T, typename... Types>
+struct ApplyConstVisitor1<index, V, R, T, Types...> {
+  R operator()(size_t runtimeIndex, V&& visitor, void* ptr) const {
+    return runtimeIndex == 1
+        ? visitor(static_cast<const T*>(ptr))
+        : ApplyConstVisitor1<index - 1, V, R, Types...>()(
+              runtimeIndex - 1, std::forward<V>(visitor), ptr);
   }
 };
 
 template <typename V, typename... Types>
-struct ApplyVisitor
-  : ApplyVisitor1<
-      V, typename VisitorResult<V, Types...>::type, Types...> {
-};
+using ApplyVisitor = ApplyVisitor1<
+    sizeof...(Types),
+    V,
+    typename VisitorResult<V, Types...>::type,
+    Types...>;
 
 template <typename V, typename... Types>
-struct ApplyConstVisitor
-  : ApplyConstVisitor1<
-      V, typename ConstVisitorResult<V, Types...>::type, Types...> {
-};
+using ApplyConstVisitor = ApplyConstVisitor1<
+    sizeof...(Types),
+    V,
+    typename ConstVisitorResult<V, Types...>::type,
+    Types...>;
 
 }  // namespace dptr_detail
 }  // namespace folly