#define LLVM_ADT_STLEXTRAS_H
#include "llvm/Support/Compiler.h"
+#include <cassert>
#include <cstddef> // for std::size_t
#include <cstdlib> // for qsort
#include <functional>
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) {
- return reinterpret_cast<Callable&>(*callable)(
+ 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)
- : callback(callback_fn<Callable>),
- callable(reinterpret_cast<void *>(&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<intptr_t>(&callable)) {}
Ret operator()(Params ...params) const {
return callback(callable, std::forward<Params>(params)...);
}
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) {
- return reinterpret_cast<Callable&>(*callable)();
+ static Ret callback_fn(intptr_t callable) {
+ return (*reinterpret_cast<Callable*>(callable))();
}
public:
template<typename Callable>
- function_ref(Callable &&callable)
- : callback(callback_fn<Callable>),
- callable(reinterpret_cast<void *>(&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<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) {
- return reinterpret_cast<Callable&>(*callable)(
+ 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)
- : callback(callback_fn<Callable>),
- callable(reinterpret_cast<void *>(&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<intptr_t>(&callable)) {}
Ret operator()(Param1 param1) {
return callback(callable, std::forward<Param1>(param1));
}
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) {
- return reinterpret_cast<Callable&>(*callable)(
+ static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2) {
+ return (*reinterpret_cast<Callable*>(callable))(
std::forward<Param1>(param1),
std::forward<Param2>(param2));
}
public:
template<typename Callable>
- function_ref(Callable &&callable)
- : callback(callback_fn<Callable>),
- callable(reinterpret_cast<void *>(&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<intptr_t>(&callable)) {}
Ret operator()(Param1 param1, Param2 param2) {
return callback(callable,
std::forward<Param1>(param1),
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)(
+ return (*reinterpret_cast<Callable*>(callable))(
std::forward<Param1>(param1),
std::forward<Param2>(param2),
std::forward<Param3>(param3));
public:
template<typename Callable>
- function_ref(Callable &&callable)
- : callback(callback_fn<Callable>),
- callable(reinterpret_cast<void *>(&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<intptr_t>(&callable)) {}
Ret operator()(Param1 param1, Param2 param2, Param3 param3) {
return callback(callable,
std::forward<Param1>(param1),
#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