Adds writer test case for RCU
[folly.git] / folly / detail / DiscriminatedPtrDetail.h
index f510a67c39b53dff10d982dd7732206aa9dd9a5a..24e9f7c273b9f7f1c4aefc4b5946a310c7692bf8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2011-present Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#ifndef FOLLY_DETAIL_DISCRIMINATEDPTRDETAIL_H_
-#define FOLLY_DETAIL_DISCRIMINATEDPTRDETAIL_H_
+#pragma once
 
 #include <type_traits>
+#include <utility>
 
 namespace folly {
 namespace dptr_detail {
@@ -110,56 +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...> {
-};
-
-}  // namespace dptr_detail
-}  // namespace folly
-
-#endif /* FOLLY_DETAIL_DISCRIMINATEDPTRDETAIL_H_ */
-
+using ApplyConstVisitor = ApplyConstVisitor1<
+    sizeof...(Types),
+    V,
+    typename ConstVisitorResult<V, Types...>::type,
+    Types...>;
+
+} // namespace dptr_detail
+} // namespace folly