Refactor is_simple_allocator and callers
authorYedidya Feldblum <yfeldblum@fb.com>
Thu, 2 Nov 2017 16:55:29 +0000 (09:55 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 2 Nov 2017 17:19:05 +0000 (10:19 -0700)
Summary:
[Folly] Refactor `is_simple_allocator` and callers.

* Swap order of template parameters.
* Do decaying in the callers instead.
* Do a direct invocability test, rather than an indirect test of whether the allocator has a method `destroy` with the expected signature.

Reviewed By: ericniebler

Differential Revision: D6184062

fbshipit-source-id: aec32e6e323b8c6023b94c258ab2bcddd8c53e09

folly/Memory.h
folly/test/ArenaSmartPtrTest.cpp

index 446d889..ce0ff05 100644 (file)
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <folly/Traits.h>
+#include <folly/functional/Invoke.h>
 
 #include <cstddef>
 #include <cstdlib>
@@ -24,6 +25,7 @@
 #include <limits>
 #include <memory>
 #include <stdexcept>
+#include <type_traits>
 #include <utility>
 
 namespace folly {
@@ -344,25 +346,23 @@ class allocator_delete
   }
 };
 
-template <typename T, typename Allocator>
-class is_simple_allocator {
-  FOLLY_CREATE_HAS_MEMBER_FN_TRAITS(has_destroy, destroy);
+namespace detail {
 
-  typedef typename std::remove_const<
-    typename std::remove_reference<Allocator>::type
-  >::type allocator;
-  typedef typename std::remove_reference<T>::type value_type;
-  typedef value_type* pointer;
+FOLLY_CREATE_MEMBER_INVOKE_TRAITS(destroy_invoke_traits, destroy);
 
- public:
-  constexpr static bool value = !has_destroy<allocator, void(pointer)>::value
-    && !has_destroy<allocator, void(void*)>::value;
-};
+} // namespace detail
+
+template <typename Allocator, typename Value>
+using is_simple_allocator =
+    Negation<detail::destroy_invoke_traits::is_invocable<Allocator, Value*>>;
 
 template <typename T, typename Allocator>
 struct as_stl_allocator {
   typedef typename std::conditional<
-    is_simple_allocator<T, Allocator>::value,
+    is_simple_allocator<
+      typename std::remove_reference<Allocator>::type,
+      typename std::remove_reference<T>::type
+    >::value,
     folly::StlAllocator<
       typename std::remove_reference<Allocator>::type,
       typename std::remove_reference<T>::type
@@ -373,7 +373,10 @@ struct as_stl_allocator {
 
 template <typename T, typename Allocator>
 typename std::enable_if<
-  is_simple_allocator<T, Allocator>::value,
+  is_simple_allocator<
+    typename std::remove_reference<Allocator>::type,
+    typename std::remove_reference<T>::type
+  >::value,
   folly::StlAllocator<
     typename std::remove_reference<Allocator>::type,
     typename std::remove_reference<T>::type
@@ -387,7 +390,10 @@ typename std::enable_if<
 
 template <typename T, typename Allocator>
 typename std::enable_if<
-  !is_simple_allocator<T, Allocator>::value,
+  !is_simple_allocator<
+    typename std::remove_reference<Allocator>::type,
+    typename std::remove_reference<T>::type
+  >::value,
   typename std::remove_reference<Allocator>::type
 >::type make_stl_allocator(Allocator&& allocator) {
   return std::move(allocator);
@@ -405,7 +411,10 @@ struct AllocatorUniquePtr {
   typedef std::unique_ptr<T,
     folly::allocator_delete<
       typename std::conditional<
-        is_simple_allocator<T, Allocator>::value,
+        is_simple_allocator<
+          typename std::remove_reference<Allocator>::type,
+          typename std::remove_reference<T>::type
+        >::value,
         folly::StlAllocator<typename std::remove_reference<Allocator>::type, T>,
         typename std::remove_reference<Allocator>::type
       >::type
index ee94db0..bad1af5 100644 (file)
@@ -25,7 +25,7 @@
 using namespace folly;
 
 static_assert(
-  is_simple_allocator<int,SysArena>::value,
+  is_simple_allocator<SysArena, int>::value,
   "SysArena should be a simple allocator"
 );