Re-sort #include lines using my handy dandy ./utils/sort_includes.py
[oota-llvm.git] / include / llvm / ADT / STLExtras.h
index 807ec59061d2c55679d195231fc52ef9bfa8573a..b10a4f11f85710c2335dcb211cd7f3d38ac54c1a 100644 (file)
@@ -18,6 +18,7 @@
 #define LLVM_ADT_STLEXTRAS_H
 
 #include "llvm/Support/Compiler.h"
+#include <cassert>
 #include <cstddef> // for std::size_t
 #include <cstdlib> // for qsort
 #include <functional>
@@ -67,20 +68,23 @@ template<typename Fn> class function_ref;
 
 template<typename Ret, typename ...Params>
 class function_ref<Ret(Params...)> {
-  Ret (*callback)(void *callable, Params ...params);
-  void *callable;
+  Ret (*callback)(intptr_t callable, Params ...params);
+  intptr_t callable;
 
   template<typename Callable>
-  static Ret callback_fn(void *callable, Params ...params) {
+  static Ret callback_fn(intptr_t callable, Params ...params) {
     return (*reinterpret_cast<Callable*>(callable))(
         std::forward<Params>(params)...);
   }
 
 public:
-  template<typename Callable>
-  function_ref(Callable &&callable)
+  template <typename Callable>
+  function_ref(Callable &&callable,
+               typename std::enable_if<
+                   !std::is_same<typename std::remove_reference<Callable>::type,
+                                 function_ref>::value>::type * = nullptr)
       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
-        callable(reinterpret_cast<void *>(&callable)) {}
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
   Ret operator()(Params ...params) const {
     return callback(callable, std::forward<Params>(params)...);
   }
@@ -90,38 +94,44 @@ public:
 
 template<typename Ret>
 class function_ref<Ret()> {
-  Ret (*callback)(void *callable);
-  void *callable;
+  Ret (*callback)(intptr_t callable);
+  intptr_t callable;
 
   template<typename Callable>
-  static Ret callback_fn(void *callable) {
+  static Ret callback_fn(intptr_t callable) {
     return (*reinterpret_cast<Callable*>(callable))();
   }
 
 public:
   template<typename Callable>
-  function_ref(Callable &&callable)
+  function_ref(Callable &&callable,
+               typename std::enable_if<
+                   !std::is_same<typename std::remove_reference<Callable>::type,
+                                 function_ref>::value>::type * = nullptr)
       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
-        callable(reinterpret_cast<void *>(&callable)) {}
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
   Ret operator()() const { return callback(callable); }
 };
 
 template<typename Ret, typename Param1>
 class function_ref<Ret(Param1)> {
-  Ret (*callback)(void *callable, Param1 param1);
-  void *callable;
+  Ret (*callback)(intptr_t callable, Param1 param1);
+  intptr_t callable;
 
   template<typename Callable>
-  static Ret callback_fn(void *callable, Param1 param1) {
+  static Ret callback_fn(intptr_t callable, Param1 param1) {
     return (*reinterpret_cast<Callable*>(callable))(
         std::forward<Param1>(param1));
   }
 
 public:
   template<typename Callable>
-  function_ref(Callable &&callable)
+  function_ref(Callable &&callable,
+               typename std::enable_if<
+                   !std::is_same<typename std::remove_reference<Callable>::type,
+                                 function_ref>::value>::type * = nullptr)
       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
-        callable(reinterpret_cast<void *>(&callable)) {}
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
   Ret operator()(Param1 param1) {
     return callback(callable, std::forward<Param1>(param1));
   }
@@ -129,11 +139,11 @@ public:
 
 template<typename Ret, typename Param1, typename Param2>
 class function_ref<Ret(Param1, Param2)> {
-  Ret (*callback)(void *callable, Param1 param1, Param2 param2);
-  void *callable;
+  Ret (*callback)(intptr_t callable, Param1 param1, Param2 param2);
+  intptr_t callable;
 
   template<typename Callable>
-  static Ret callback_fn(void *callable, Param1 param1, Param2 param2) {
+  static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2) {
     return (*reinterpret_cast<Callable*>(callable))(
         std::forward<Param1>(param1),
         std::forward<Param2>(param2));
@@ -141,9 +151,12 @@ class function_ref<Ret(Param1, Param2)> {
 
 public:
   template<typename Callable>
-  function_ref(Callable &&callable)
+  function_ref(Callable &&callable,
+               typename std::enable_if<
+                   !std::is_same<typename std::remove_reference<Callable>::type,
+                                 function_ref>::value>::type * = nullptr)
       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
-        callable(reinterpret_cast<void *>(&callable)) {}
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
   Ret operator()(Param1 param1, Param2 param2) {
     return callback(callable,
                     std::forward<Param1>(param1),
@@ -153,11 +166,11 @@ public:
 
 template<typename Ret, typename Param1, typename Param2, typename Param3>
 class function_ref<Ret(Param1, Param2, Param3)> {
-  Ret (*callback)(void *callable, Param1 param1, Param2 param2, Param3 param3);
-  void *callable;
+  Ret (*callback)(intptr_t callable, Param1 param1, Param2 param2, Param3 param3);
+  intptr_t callable;
 
   template<typename Callable>
-  static Ret callback_fn(void *callable, Param1 param1, Param2 param2,
+  static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2,
                          Param3 param3) {
     return (*reinterpret_cast<Callable*>(callable))(
         std::forward<Param1>(param1),
@@ -167,9 +180,12 @@ class function_ref<Ret(Param1, Param2, Param3)> {
 
 public:
   template<typename Callable>
-  function_ref(Callable &&callable)
+  function_ref(Callable &&callable,
+               typename std::enable_if<
+                   !std::is_same<typename std::remove_reference<Callable>::type,
+                                 function_ref>::value>::type * = nullptr)
       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
-        callable(reinterpret_cast<void *>(&callable)) {}
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
   Ret operator()(Param1 param1, Param2 param2, Param3 param3) {
     return callback(callable,
                     std::forward<Param1>(param1),
@@ -530,6 +546,48 @@ make_unique(size_t n) {
 
 #endif
 
+struct FreeDeleter {
+  void operator()(void* v) {
+    ::free(v);
+  }
+};
+
+template<typename First, typename Second>
+struct pair_hash {
+  size_t operator()(const std::pair<First, Second> &P) const {
+    return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
+  }
+};
+
+/// A functor like C++14's std::less<void> in its absence.
+struct less {
+  template <typename A, typename B> bool operator()(A &&a, B &&b) const {
+    return std::forward<A>(a) < std::forward<B>(b);
+  }
+};
+
+/// A functor like C++14's std::equal<void> in its absence.
+struct equal {
+  template <typename A, typename B> bool operator()(A &&a, B &&b) const {
+    return std::forward<A>(a) == std::forward<B>(b);
+  }
+};
+
+/// Binary functor that adapts to any other binary functor after dereferencing
+/// operands.
+template <typename T> struct deref {
+  T func;
+  // Could be further improved to cope with non-derivable functors and
+  // non-binary functors (should be a variadic template member function
+  // operator()).
+  template <typename A, typename B>
+  auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
+    assert(lhs);
+    assert(rhs);
+    return func(*lhs, *rhs);
+  }
+};
+
 } // End llvm namespace
 
 #endif