Add logging for comparison behaviors
[hiphop-php.git] / hphp / util / type-traits.h
blobbc04ca1ae21fce5ab5136f2475b891ac298a8a11
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_UTIL_TYPE_TRAITS_H_
18 #define incl_HPHP_UTIL_TYPE_TRAITS_H_
20 #include <type_traits>
21 #include <functional>
23 namespace HPHP {
25 ///////////////////////////////////////////////////////////////////////////////
27 template<typename T>
28 constexpr auto identity(T&& t) noexcept -> decltype(std::forward<T>(t)) {
29 return std::forward<T>(t);
32 ///////////////////////////////////////////////////////////////////////////////
35 * Is `T' the same type as `U' or any type in `Tail...'?
37 template<class T, class U, class... Tail> struct is_any;
39 template<class T, class U>
40 struct is_any<T,U> : std::is_same<T,U> {};
42 template<class T, class U, class V, class... Tail>
43 struct is_any<T,U,V,Tail...> : std::integral_constant<
44 bool,
45 std::is_same<T,U>::value || is_any<T,V,Tail...>::value
46 > {};
48 ///////////////////////////////////////////////////////////////////////////////
51 * Identity functor.
53 template<typename T> struct ident { using type = T; };
54 template<typename T> using ident_t = typename ident<T>::type;
57 * Stateless tuple for parameter unpacking.
59 template<typename...> struct pack {};
62 * Clone of std::conjunction<>.
64 template<class...> struct conjunction : std::true_type { };
65 template<class B1> struct conjunction<B1> : B1 { };
66 template<class B1, class... Bn>
67 struct conjunction<B1, Bn...>
68 : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
71 * Clone of std::disjunction<>.
73 template<class...> struct disjunction : std::false_type { };
74 template<class B1> struct disjunction<B1> : B1 { };
75 template<class B1, class... Bn>
76 struct disjunction<B1, Bn...>
77 : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>> {};
80 * Helper for appending a type parameter to a template class's variadic
81 * parameter list.
83 template<typename Head, typename Tail> struct cons;
84 template<template<typename...> class List, typename T, typename... Args>
85 struct cons<T, List<Args...>> {
86 using type = List<T, Args...>;
89 ///////////////////////////////////////////////////////////////////////////////
92 * Whether `T' and `U' are the same type, with the outermost const-qualifier
93 * stripped away.
95 template<class T, class U>
96 using is_same_upto_const = std::is_same<
97 typename std::remove_const<T>::type,
98 typename std::remove_const<U>::type
101 namespace detail {
103 template<class... Ts> struct maybe_const_pred;
105 template<>
106 struct maybe_const_pred<> : std::true_type {};
108 template<class T>
109 struct maybe_const_pred<T> : std::true_type {};
111 template<class T, class U, class... Tail>
112 struct maybe_const_pred<T, U, Tail...> : std::integral_constant<
113 bool,
114 is_same_upto_const<T,U>::value &&
115 maybe_const_pred<Tail...>::value
116 > {};
118 template<class... Ts> struct maybe_const_result;
120 template<>
121 struct maybe_const_result<> { using type = void; };
123 template<class R>
124 struct maybe_const_result<R> { using type = R; };
126 template<class T, class U, class... Tail>
127 struct maybe_const_result<T, U, Tail...> : maybe_const_result<Tail...> {};
132 * Pattern for templatizing functions to take an optionally-const argument.
133 * Writing
135 * template<class T1, class T2, ...>
136 * maybe_const<T1, K1, T2, K2, ..., R>::type
138 * is equivalent to
140 * template<class T1, class T2, ...>
141 * std::enable_if<
142 * is_same_upto_const<T1, K1>::value &&
143 * is_same_upto_const<T2, K2>::value &&
144 * ...,
146 * >::type
148 template<class T, class K, class... Tail>
149 using maybe_const = std::enable_if<
150 detail::maybe_const_pred<T, K, Tail...>::value,
151 typename detail::maybe_const_result<T, K, Tail...>::type
154 template <typename Fn, typename ... Args>
155 struct is_invocable : public std::is_constructible<
156 std::function<void(Args ...)>, Fn&&
157 > {};
159 ///////////////////////////////////////////////////////////////////////////////
163 #endif