rttr  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
misc_type_traits.h
Go to the documentation of this file.
1 /************************************************************************************
2 * *
3 * Copyright (c) 2014 Axel Menzel <info@axelmenzel.de> *
4 * *
5 * This file is part of RTTR (Run Time Type Reflection) *
6 * License: MIT License *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining *
9 * a copy of this software and associated documentation files (the "Software"), *
10 * to deal in the Software without restriction, including without limitation *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
12 * and/or sell copies of the Software, and to permit persons to whom the *
13 * Software is furnished to do so, subject to the following conditions: *
14 * *
15 * The above copyright notice and this permission notice shall be included in *
16 * all copies or substantial portions of the Software. *
17 * *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
24 * SOFTWARE. *
25 * *
26 *************************************************************************************/
27 
28 #ifndef __RTTR_MISC_TYPE_TRAITS_H__
29 #define __RTTR_MISC_TYPE_TRAITS_H__
30 
32 
34 
35 #include <type_traits>
36 
37 namespace rttr
38 {
39 
40 class type;
41 
42 namespace detail
43 {
44  struct derived_info;
45 
46  template<class T>
47  struct raw_type { typedef T type; };
48 
49  template<class T> struct raw_type<const T> { typedef typename raw_type<T>::type type; };
50 
51  template<class T> struct raw_type<T*> { typedef typename raw_type<T>::type type; };
52  template<class T> struct raw_type<T* const> { typedef typename raw_type<T>::type type; };
53  template<class T> struct raw_type<T* volatile> { typedef typename raw_type<T>::type type; };
54 
55  template<class T> struct raw_type<T&> { typedef typename raw_type<T>::type type; };
56  template<class T, std::size_t N>
57  struct raw_type<const T[N]> { typedef typename raw_type<T[N]>::type type; };
58 
59 
61 
62  template <bool... b> struct static_all_of;
63  //specialization for type true, go continue recurse if the first argument is true
64  template <bool... tail>
65  struct static_all_of<true, tail...> : static_all_of<tail...> {};
66  // end recursion if first argument is false
67  template <bool... tail>
68  struct static_all_of<false, tail...> : std::false_type {};
69 
70  // finish when no argument are left
71  template <> struct static_all_of<> : std::true_type {};
72 
73  // use it like e.g.:
74  // static_all_of<std::is_class<ClassType>::value...>::value
75 
77 
78  template <bool... b> struct static_any_of;
79 
80  template <bool... tail>
81  struct static_any_of<true, tail...> : std::true_type {};
82 
83  template <bool... tail>
84  struct static_any_of<false, tail...> : static_any_of<tail...> {};
85 
86  // finish when no argument are left
87  template <> struct static_any_of<> : std::false_type {};
88 
90 
94  template <typename T>
95  class has_get_type_func_impl
96  {
97  typedef char YesType[1];
98  typedef char NoType[2];
99 
100  template <typename U, rttr::type (U::*)() const>
101  class check { };
102 
103  template <typename C>
104  static YesType& f(check<C, &C::get_type>*);
105 
106  template <typename C>
107  static NoType& f(...);
108 
109  public:
110  static const bool value = (sizeof(f<typename raw_type<T>::type>(0)) == sizeof(YesType));
111  };
112 
116  template<class T, typename Enable = void>
117  struct has_get_type_func : std::false_type
118  {};
119 
120  template<class T>
121  struct has_get_type_func<T, typename std::enable_if<has_get_type_func_impl<T>::value>::type > : std::true_type
122  {};
123 
125 
130  template <typename T>
131  class has_get_ptr_func_impl
132  {
133  typedef char YesType[1];
134  typedef char NoType[2];
135 
136  template <typename U, void* (U::*)()>
137  class check { };
138 
139  template <typename C>
140  static YesType& f(check<C, &C::get_ptr>*);
141 
142  template <typename C>
143  static NoType& f(...);
144 
145  public:
146  static const bool value = (sizeof(f<typename raw_type<T>::type>(0)) == sizeof(YesType));
147  };
148 
152  template<class T, typename Enable = void>
153  struct has_get_ptr_func : std::false_type
154  {};
155 
156  template<class T>
157  struct has_get_ptr_func<T, typename std::enable_if<has_get_ptr_func_impl<T>::value>::type > : std::true_type
158  {};
159 
161 
166  template <typename T>
167  class has_get_derived_info_func_impl
168  {
169  typedef char YesType[1];
170  typedef char NoType[2];
171 
172  template <typename U, derived_info (U::*)()>
173  class check { };
174 
175  template <typename C>
176  static YesType& f(check<C, &C::get_derived_info>*);
177 
178  template <typename C>
179  static NoType& f(...);
180 
181  public:
182  static const bool value = (sizeof(f<typename raw_type<T>::type>(0)) == sizeof(YesType));
183  };
184 
188  template<class T, typename Enable = void>
189  struct has_get_derived_info_func : std::false_type
190  {};
191 
192  template<class T>
193  struct has_get_derived_info_func<T, typename std::enable_if<has_get_derived_info_func_impl<T>::value>::type > : std::true_type
194  {};
195 
197 
198  template<typename T>
199  struct get_ptr_impl
200  {
201  static RTTR_INLINE void* get(T& data)
202  {
203  return const_cast<void*>(reinterpret_cast<const void*>(&data));
204  }
205  };
206 
207  template<typename T>
208  struct get_ptr_impl<T*>
209  {
210  static RTTR_INLINE void* get(T* data)
211  {
212  return get_ptr_impl<T>::get(*data);
213  }
214  };
215 
216  template<>
217  struct get_ptr_impl<void*>
218  {
219  static RTTR_INLINE void* get(void* data)
220  {
221  return data;
222  }
223  };
224 
225  template<>
226  struct get_ptr_impl<const void*>
227  {
228  static RTTR_INLINE void* get(const void* data)
229  {
230  return const_cast<void*>(data);
231  }
232  };
233 
234  template<typename T>
235  static RTTR_INLINE void* get_void_ptr(T* data)
236  {
237  return get_ptr_impl<T*>::get(data);
238  }
239 
240  template<typename T>
241  static RTTR_INLINE void* get_void_ptr(T& data)
242  {
243  return get_ptr_impl<T>::get(data);
244  }
245 
247 
248  template<typename T, typename... Types>
249  struct contains : static_any_of<std::is_same<T, Types>::value...>
250  {
251  };
252 
253  template<typename T, typename... Types, template<class...> class TContainer>
254  struct contains<T, TContainer<Types...>> : contains<T, Types...>
255  {
256  };
257 
259 
260  template <typename T>
261  struct is_array_impl
262  {
263  typedef char YesType[1];
264  typedef char NoType[2];
265 
266  template <typename U> static NoType& check(typename U::no_array_type*);
267  template <typename U> static YesType& check(...);
268 
269 
270  static const bool value = (sizeof(check<array_mapper<T> >(0)) == sizeof(YesType));
271  };
272 
273  template<class T>
274  struct is_array : std::conditional<is_array_impl<T>::value,
275  std::true_type,
276  std::false_type>::type
277  {};
278 
280  // rank_type<T, size_t>::type
281  //
282  // rank_type<int[2][10][4], 0>::type => int[2][10][4]
283  // rank_type<int[2][10][4], 1>::type => int[10][4]
284  // rank_type<int[2][10][4], 2>::type => int[4]
285  // works of course with all other class, which has an array_mapper specialization
286 
287  template <typename... T>
288  struct concat_array_types;
289 
290 
291  template <template <typename ...> class List, typename ...Types, typename T>
292  struct concat_array_types<List<Types...>, T, std::true_type>
293  {
294  using type = List<Types...>;
295  };
296 
297  template <template <typename... > class List, typename... Types, typename T>
298  struct concat_array_types<List<Types...>, T, std::false_type>
299  {
300  using sub_type = typename array_mapper<T>::sub_type;
301  using type = typename concat_array_types< List<Types..., T>, sub_type, typename std::is_same<T, sub_type>::type>::type;
302  };
303 
304  template<typename T>
305  struct array_rank_type_list
306  {
307  using sub_type = typename array_mapper<T>::sub_type;
308  using types = typename concat_array_types< std::tuple<>, T, typename std::is_same<T, sub_type>::type>::type;
309  };
310 
311  template<typename T, size_t N>
312  struct rank_type
313  {
314  using type = typename std::tuple_element<N, typename array_rank_type_list<T>::types>::type;
315  };
316 
318  // rank<T>::value
319  //
320  // rank<int[2][10][4]>::value => 3
321  // rank<std::vector<std::vector<int>>>::value => 2
322  template <typename... T>
323  struct rank_impl
324  {
325  using type = typename std::integral_constant<std::size_t, 0>::type;
326  };
327 
328  template <template <typename... > class List, typename... Types>
329  struct rank_impl<List<Types...>>
330  {
331  using type = typename std::integral_constant<std::size_t, sizeof...(Types) - 1>::type;
332  };
333 
334  template<typename T>
335  using rank = typename rank_impl< typename detail::array_rank_type_list<T>::types >::type;
336 
338  // pointer_count<T>::value Returns the number of pointers for a type
339  // e.g. pointer_count<char**>::value => 2
340  // pointer_count<char*>::value => 1
341  // pointer_count<char>::value => 0
342  template<typename T>
343  struct pointer_count_impl
344  {
345  static const std::size_t size = 0;
346  };
347 
348 
349  template<typename T>
350  struct pointer_count_impl<T*>
351  {
352  static const std::size_t size = pointer_count_impl<T>::size + 1;
353  };
354 
355  //template<typename T>
356  //using pointer_count = std::integral_constant<std::size_t, pointer_count_impl<T>::size>;
357  template<typename T>
358  struct pointer_count : std::integral_constant<std::size_t, pointer_count_impl<T>::size>
359  {};
360 
362  // is_char_array<T>::value Returns true if the given typ is a char array
363  // e.g. is_char_array<char[10]>::value => true
364  // is_char_array<int[10]>::value => false
365  // is_char_array<char>::value => false
366  template<typename T>
367  struct char_array_impl : std::false_type
368  {
369  };
370 
371 
372  template<std::size_t N>
373  struct char_array_impl<char[N]> : std::true_type
374  {
375  };
376 
377  template<typename T>
378  using is_char_array = char_array_impl<T>;
379 
380  template<typename T>
381  struct is_one_dim_char_array : std::integral_constant<bool, is_char_array<T>::value && (std::rank<T>::value == 1)>
382  {};
383 
384  template<typename T>
385  struct is_array_and_not_one_dim_char_array : std::integral_constant<bool, std::is_array<T>::value && !is_one_dim_char_array<T>::value>
386  {
387 
388  };
389 
391 
392 } // end namespace detail
393 
394 } // end namespace rttr
395 
396 #endif // __RTTR_MISC_TYPE_TRAITS_H__
#define RTTR_INLINE
Definition: core_prerequisites.h:90