20 #ifndef DIY_UTILS_TRAITS_HPP
21 #define DIY_UTILS_TRAITS_HPP
26 #include <type_traits>
49 #define DECLARE_HAS_TYPE_MEMBER(member_name) \
50 template <typename, typename = void> \
51 struct has_##member_name \
52 { enum { value = false }; }; \
53 template <typename T> \
54 struct has_##member_name<T, typename std::enable_if<sizeof(typename T::member_name)||true>::type> \
55 { enum { value = true }; };
74 struct function_traits
75 :
public function_traits<decltype(&T::operator())>
80 template <
typename C,
typename R,
typename... A>
83 typedef typename std::conditional<
84 std::is_const<C>::value,
85 typename std::conditional<
86 std::is_volatile<C>::value,
87 R (C::*)(A...)
const volatile,
90 typename std::conditional<
91 std::is_volatile<C>::value,
92 R (C::*)(A...)
volatile,
99 template <
typename ReturnType,
typename... Args>
100 struct function_traits<ReturnType(Args...)>
107 typedef ReturnType result_type;
114 typedef ReturnType function_type(Args...);
121 template <
typename OwnerType>
122 using member_function_type =
typename xx_impl::memfn_type<
123 typename std::remove_pointer<typename std::remove_reference<OwnerType>::type>::type,
132 enum { arity =
sizeof...(Args) };
142 typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
146 template <
typename ReturnType,
typename... Args>
147 struct function_traits<ReturnType(*)(Args...)>
148 :
public function_traits<ReturnType(Args...)>
151 template <
typename ClassType,
typename ReturnType,
typename... Args>
152 struct function_traits<ReturnType(ClassType::*)(Args...)>
153 :
public function_traits<ReturnType(Args...)>
155 typedef ClassType& owner_type;
158 template <
typename ClassType,
typename ReturnType,
typename... Args>
159 struct function_traits<ReturnType(ClassType::*)(Args...) const>
160 :
public function_traits<ReturnType(Args...)>
162 typedef const ClassType& owner_type;
165 template <
typename ClassType,
typename ReturnType,
typename... Args>
166 struct function_traits<ReturnType(ClassType::*)(Args...) volatile>
167 :
public function_traits<ReturnType(Args...)>
169 typedef volatile ClassType& owner_type;
172 template <
typename ClassType,
typename ReturnType,
typename... Args>
173 struct function_traits<ReturnType(ClassType::*)(Args...) const volatile>
174 :
public function_traits<ReturnType(Args...)>
176 typedef const volatile ClassType& owner_type;
179 template <
typename FunctionType>
180 struct function_traits<std::function<FunctionType>>
181 :
public function_traits<FunctionType>
184 #if defined(_GLIBCXX_FUNCTIONAL)
185 #define MEM_FN_SYMBOL_XX0SL7G4Z0J std::_Mem_fn
186 #elif defined(_LIBCPP_FUNCTIONAL)
187 #define MEM_FN_SYMBOL_XX0SL7G4Z0J std::__mem_fn
190 #ifdef MEM_FN_SYMBOL_XX0SL7G4Z0J
192 template <
typename R,
typename C>
193 struct function_traits<MEM_FN_SYMBOL_XX0SL7G4Z0J<R C::*>>
194 :
public function_traits<R(C*)>
196 template <
typename R,
typename C,
typename... A>
197 struct function_traits<MEM_FN_SYMBOL_XX0SL7G4Z0J<R(C::*)(A...)>>
198 :
public function_traits<R(C*, A...)>
200 template <
typename R,
typename C,
typename... A>
201 struct function_traits<MEM_FN_SYMBOL_XX0SL7G4Z0J<R(C::*)(A...) const>>
202 :
public function_traits<R(const C*, A...)>
204 template <
typename R,
typename C,
typename... A>
205 struct function_traits<MEM_FN_SYMBOL_XX0SL7G4Z0J<R(C::*)(A...) volatile>>
206 :
public function_traits<R(volatile C*, A...)>
208 template <
typename R,
typename C,
typename... A>
209 struct function_traits<MEM_FN_SYMBOL_XX0SL7G4Z0J<R(C::*)(A...) const volatile>>
210 :
public function_traits<R(const volatile C*, A...)>
213 #undef MEM_FN_SYMBOL_XX0SL7G4Z0J
216 template <
typename T>
217 struct function_traits<T&> :
public function_traits<T> {};
218 template <
typename T>
219 struct function_traits<const T&> :
public function_traits<T> {};
220 template <
typename T>
221 struct function_traits<volatile T&> :
public function_traits<T> {};
222 template <
typename T>
223 struct function_traits<const volatile T&> :
public function_traits<T> {};
224 template <
typename T>
225 struct function_traits<T&&> :
public function_traits<T> {};
226 template <
typename T>
227 struct function_traits<const T&&> :
public function_traits<T> {};
228 template <
typename T>
229 struct function_traits<volatile T&&> :
public function_traits<T> {};
230 template <
typename T>
231 struct function_traits<const volatile T&&> :
public function_traits<T> {};
234 #define FORWARD_RES_8QR485JMSBT \
235 typename std::conditional< \
236 std::is_lvalue_reference<R>::value, \
238 typename std::remove_reference<T>::type&& \
252 template <
typename R,
typename T>
253 FORWARD_RES_8QR485JMSBT forward_like(T&& input) noexcept
255 return static_cast<FORWARD_RES_8QR485JMSBT
>(input);
258 #undef FORWARD_RES_8QR485JMSBT
266 template <
typename From,
typename To>
270 typedef typename std::remove_cv<To>::type raw_To;
271 typedef typename std::conditional<std::is_const<From>::value,
272 const raw_To, raw_To>::type const_raw_To;
279 typedef typename std::conditional<std::is_volatile<From>::value,
280 volatile const_raw_To, const_raw_To>::type type;
289 template <
typename T>
297 typedef typename std::remove_reference<decltype(*std::declval<T>())>::type type;
307 template <
typename T>
308 typename std::add_rvalue_reference<T>::type rt_val() noexcept
310 return std::move(*static_cast<T*>(
nullptr));