DIY  3.0
data-parallel out-of-core C++ library
 All Classes Namespaces Functions Typedefs Groups Pages
traits.hpp
1 //--------------------------------------
2 // utils/traits: Additional type traits
3 //--------------------------------------
4 //
5 // Copyright kennytm (auraHT Ltd.) 2011.
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file doc/LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
20 #ifndef DIY_UTILS_TRAITS_HPP
21 #define DIY_UTILS_TRAITS_HPP
22 
23 #include <cstdlib>
24 #include <tuple>
25 #include <functional>
26 #include <type_traits>
27 
28 namespace diy
29 {
30 namespace detail {
31 
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 }; };
56 
73 template <typename T>
74 struct function_traits
75  : public function_traits<decltype(&T::operator())>
76 {};
77 
78 namespace xx_impl
79 {
80  template <typename C, typename R, typename... A>
81  struct memfn_type
82  {
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,
88  R (C::*)(A...) const
89  >::type,
90  typename std::conditional<
91  std::is_volatile<C>::value,
92  R (C::*)(A...) volatile,
93  R (C::*)(A...)
94  >::type
95  >::type type;
96  };
97 }
98 
99 template <typename ReturnType, typename... Args>
100 struct function_traits<ReturnType(Args...)>
101 {
107  typedef ReturnType result_type;
108 
114  typedef ReturnType function_type(Args...);
115 
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,
124  ReturnType, Args...
125  >::type;
126 
132  enum { arity = sizeof...(Args) };
133 
139  template <size_t i>
140  struct arg
141  {
142  typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
143  };
144 };
145 
146 template <typename ReturnType, typename... Args>
147 struct function_traits<ReturnType(*)(Args...)>
148  : public function_traits<ReturnType(Args...)>
149 {};
150 
151 template <typename ClassType, typename ReturnType, typename... Args>
152 struct function_traits<ReturnType(ClassType::*)(Args...)>
153  : public function_traits<ReturnType(Args...)>
154 {
155  typedef ClassType& owner_type;
156 };
157 
158 template <typename ClassType, typename ReturnType, typename... Args>
159 struct function_traits<ReturnType(ClassType::*)(Args...) const>
160  : public function_traits<ReturnType(Args...)>
161 {
162  typedef const ClassType& owner_type;
163 };
164 
165 template <typename ClassType, typename ReturnType, typename... Args>
166 struct function_traits<ReturnType(ClassType::*)(Args...) volatile>
167  : public function_traits<ReturnType(Args...)>
168 {
169  typedef volatile ClassType& owner_type;
170 };
171 
172 template <typename ClassType, typename ReturnType, typename... Args>
173 struct function_traits<ReturnType(ClassType::*)(Args...) const volatile>
174  : public function_traits<ReturnType(Args...)>
175 {
176  typedef const volatile ClassType& owner_type;
177 };
178 
179 template <typename FunctionType>
180 struct function_traits<std::function<FunctionType>>
181  : public function_traits<FunctionType>
182 {};
183 
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
188 #endif
189 
190 #ifdef MEM_FN_SYMBOL_XX0SL7G4Z0J
191 
192 template <typename R, typename C>
193 struct function_traits<MEM_FN_SYMBOL_XX0SL7G4Z0J<R C::*>>
194  : public function_traits<R(C*)>
195 {};
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...)>
199 {};
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...)>
203 {};
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...)>
207 {};
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...)>
211 {};
212 
213 #undef MEM_FN_SYMBOL_XX0SL7G4Z0J
214 #endif
215 
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> {};
232 
233 
234 #define FORWARD_RES_8QR485JMSBT \
235  typename std::conditional< \
236  std::is_lvalue_reference<R>::value, \
237  T&, \
238  typename std::remove_reference<T>::type&& \
239  >::type
240 
252 template <typename R, typename T>
253 FORWARD_RES_8QR485JMSBT forward_like(T&& input) noexcept
254 {
255  return static_cast<FORWARD_RES_8QR485JMSBT>(input);
256 }
257 
258 #undef FORWARD_RES_8QR485JMSBT
259 
266 template <typename From, typename To>
267 struct copy_cv
268 {
269 private:
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;
273 public:
279  typedef typename std::conditional<std::is_volatile<From>::value,
280  volatile const_raw_To, const_raw_To>::type type;
281 };
282 
289 template <typename T>
290 struct pointee
291 {
297  typedef typename std::remove_reference<decltype(*std::declval<T>())>::type type;
298 };
299 
307 template <typename T>
308 typename std::add_rvalue_reference<T>::type rt_val() noexcept
309 {
310  return std::move(*static_cast<T*>(nullptr));
311 }
312 
313 }
314 
315 }
316 
317 #endif
318