rttr  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
rttr_enable.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_RTTR_ENABLE_H__
29 #define __RTTR_RTTR_ENABLE_H__
30 
31 #include <type_traits>
32 
34 #include "rttr/type.h"
35 #include "rttr/variant.h"
36 
37 namespace rttr
38 {
39 
40 namespace detail
41 {
46  struct derived_info
47  {
48  void* _ptr;
49  type _type;
50  };
51 
52  struct base_class_info
53  {
54  base_class_info(type t,void*(*rttr_cast_func)(void*))
55  : _base_type(t), _rttr_cast_func(rttr_cast_func)
56  {}
57  type _base_type;
58  void* (*_rttr_cast_func)(void*);
59  };
60 }
61 
62 namespace impl
63 {
64 
66 template<typename... U> struct type_list {};
67 
69 
73 template <typename T>
74 class has_base_class_list_impl
75 {
76  typedef char YesType[1];
77  typedef char NoType[2];
78 
79  template <typename C>
80  static YesType& test(typename C::base_class_list*);
81 
82  template <typename>
83  static NoType& test(...);
84 
85 public:
86  static const bool value = (sizeof(YesType) == sizeof(test<T>(0)));
87 };
88 
92 template<typename T, typename = void>
93 struct has_base_class_list : std::integral_constant<bool, false>
94 {};
95 
96 template<typename T>
97 struct has_base_class_list<T, typename std::enable_if<has_base_class_list_impl<T>::value>::type > : std::integral_constant<bool, true>
98 {};
99 
100 typedef std::vector<detail::base_class_info> info_container;
101 
105 template<typename DerivedClass, typename... T>
106 struct type_from_base_classes;
107 
108 template<typename DerivedClass>
109 struct type_from_base_classes<DerivedClass>
110 {
111  RTTR_INLINE static void fill(info_container&)
112  {
113  }
114 };
115 
124 template<typename DerivedType, typename BaseType>
125 static void* rttr_cast_impl(void* ptr)
126 {
127  return static_cast<void*>(static_cast<BaseType*>(static_cast<DerivedType*>(ptr)));
128 }
129 
130 template<typename DerivedClass, typename BaseClass, typename... U>
131 struct type_from_base_classes<DerivedClass, BaseClass, U...>
132 {
133  RTTR_INLINE static void fill(info_container& vec)
134  {
135  static_assert(has_base_class_list<BaseClass>::value, "The parent class has no base class list defined - please use the macro RTTR_ENABLE");
136  vec.emplace_back(type::get<BaseClass>(), &rttr_cast_impl<DerivedClass, BaseClass>);
137  // retrieve also the types of all base classes of the base classes; you will get an compile error here,
138  // when the base class has not defined the 'base_class_list' typedef
139  type_from_base_classes<DerivedClass, typename BaseClass::base_class_list>::fill(vec);
140  // continue with the rest
141  type_from_base_classes<DerivedClass, U...>::fill(vec);
142  }
143 };
144 
145 template<typename DerivedClass, class... BaseClassList, template<class...> class ClassContainer>
146 struct type_from_base_classes<DerivedClass, ClassContainer<BaseClassList...>> : type_from_base_classes<DerivedClass, BaseClassList...> { };
147 
152 template<typename ClassType>
153 struct base_classes
154 {
155  private:
156  // extract the info
157  RTTR_INLINE static void get_types_impl(info_container& vec, std::true_type)
158  {
159  type_from_base_classes<ClassType, typename ClassType::base_class_list>::fill(vec);
160  }
161 
162  // no type list defined
163  RTTR_INLINE static void get_types_impl(info_container&, std::false_type)
164  {
165  }
166  public:
167  RTTR_INLINE static info_container get_types()
168  {
169  info_container result;
170  get_types_impl(result, typename has_base_class_list<ClassType>::type());
171  return result;
172  }
173 };
174 
178 template<typename T>
179 static void* get_ptr(const T& data, typename std::enable_if<!std::is_pointer<T>::value>::type* = 0)
180 {
181  return const_cast<void*>(reinterpret_cast<const void*>(&data));
182 }
183 
187 template<typename T>
188 static void* get_ptr(T& data, typename std::enable_if<!std::is_pointer<T>::value>::type* = 0)
189 {
190  return reinterpret_cast<void*>(&data);
191 }
192 
196 template<typename T>
197 static void* get_ptr(const T& data, typename std::enable_if<std::is_pointer<T>::value>::type* = 0)
198 {
199  return const_cast<void*>(reinterpret_cast<const void*>(data));
200 }
201 
205 template<typename T>
206 static void* get_ptr(T& data, typename std::enable_if<std::is_pointer<T>::value>::type* = 0)
207 {
208  return reinterpret_cast<void*>(data);
209 }
210 
212 
213 template<typename T>
214 static detail::derived_info get_most_derived_info_impl(void* ptr)
215 {
216  return (static_cast<T*>(ptr)->get_derived_info());
217 }
218 
219 template<typename T>
220 static detail::derived_info get_most_derived_info_impl_none(void* ptr)
221 {
222  return {ptr, type::get<T>()};
223 }
224 
225 typedef detail::derived_info(*derived_func)(void*);
226 
231 template<typename T>
232 static derived_func get_most_derived_info_check(typename std::enable_if<detail::has_get_derived_info_func<T>::value >::type* = 0)
233 {
234  return get_most_derived_info_impl<T>;
235 }
236 
240 template<typename T>
241 static derived_func get_most_derived_info_check(typename std::enable_if<!detail::has_get_derived_info_func<T>::value >::type* = 0)
242 {
243  return get_most_derived_info_impl_none<T>;
244 }
245 
251 template<typename T>
252 static derived_func get_most_derived_info_func()
253 {
254  return get_most_derived_info_check<typename detail::raw_type<T>::type>();
255 }
256 
257 template<typename source_type>
258 static variant create_variant(void* ptr)
259 {
260  return static_cast<source_type>(ptr);
261 }
262 
263 template<typename source_type>
264 static variant create_invalid_variant(void*)
265 {
266  return variant();
267 }
268 
269 typedef variant(*create_variant_func)(void*);
270 
271 template<typename T>
272 create_variant_func get_create_variant_func(typename std::enable_if< detail::pointer_count<T>::value == 1 >::type* = 0)
273 {
274  return create_variant<T>;
275 }
276 
277 template<typename T>
278 create_variant_func get_create_variant_func(typename std::enable_if< detail::pointer_count<T>::value != 1>::type* = 0)
279 {
280  return create_invalid_variant<T>;
281 }
282 
283 } // end namespace impl
284 } // end namespace rttr
285 
286 #define TYPE_LIST(...) rttr::impl::type_list<__VA_ARGS__>
287 
288 #define RTTR_ENABLE(...) \
289 public:\
290  virtual RTTR_INLINE rttr::type get_type() const { return rttr::impl::get_type_from_instance(this); } \
291  virtual RTTR_INLINE void* get_ptr() { return reinterpret_cast<void*>(this); } \
292  virtual RTTR_INLINE rttr::detail::derived_info get_derived_info() { return {reinterpret_cast<void*>(this), rttr::impl::get_type_from_instance(this)}; } \
293  typedef TYPE_LIST(__VA_ARGS__) base_class_list; \
294 private:
295 
296 
297 #endif // __RTTR_RTTR_ENABLE_H__
#define RTTR_INLINE
Definition: core_prerequisites.h:90