4 #include <cgv/type/info/type_name.h>
5 #include <cgv/utils/convert.h>
6 #include <cgv/utils/token.h>
7 #include <cgv/type/traits/method_pointer.h>
8 #include <cgv/type/info/type_id.h>
10 #include "self_reflection_tag.h"
11 #include "reflection_traits_info.h"
13 #include "lib_begin.h"
25 virtual void call_void(
void* instance,
26 const std::vector<abst_reflection_traits*>& param_value_traits,
27 const std::vector<const void*>& param_value_ptrs,
28 const std::vector<std::string>& param_type_names,
30 void* result_value_ptr = 0,
31 const std::string& result_type =
"") = 0;
34 template <
int i,
int n,
typename M>
35 struct method_parameter_traits_helper
37 static void fill_vector(std::vector<abst_reflection_traits*>& param_value_traits)
41 method_parameter_traits_helper<i+1,n,M>::fill_vector(param_value_traits);
45 template <
int i,
typename M>
46 struct method_parameter_traits_helper<i,i,M>
48 static void fill_vector(std::vector<abst_reflection_traits*>& param_value_traits)
55 struct method_interface_impl;
64 #ifndef REFLECT_TRAITS_WITH_DECLTYPE
65 template <
typename B,
typename RB>
66 bool reflect_base_impl(B& base_ref,
const RB&);
67 template <
typename T,
unsigned n,
typename RT>
68 bool reflect_const_array_impl(
const std::string& member_name, T (&member_ref)[n],
const RT&);
69 template <
typename T,
typename RT>
70 bool reflect_vector_impl(
const std::string& member_name, std::vector<T>& member_ref,
const RT&);
74 friend bool reflect_enum(
reflection_handler& rh,
const std::string& name, T& instance,
const std::string& declarations);
76 friend bool reflect_string(
reflection_handler& rh,
const std::string& name, T& instance);
80 enum GroupTraversal { GT_TERMINATE = -3, GT_SKIP = -2, GT_COMPLETE = -1 };
85 enum GroupKind { GK_NO_GROUP, GK_BASE_CLASS, GK_STRUCTURE, GK_VECTOR, GK_ARRAY, GK_POINTER };
87 static const char* group_kind_name(GroupKind gk);
89 static bool is_array_kind(GroupKind gk);
94 GroupTraversal process_structural_group_begin(GroupKind gk,
const std::string& member_name, GroupTraversal gt);
97 bool group_end(GroupKind gk);
99 template <
typename T,
typename RT,
typename D>
100 bool self_reflect_member(
const std::string& member_name, T& member_ref,
const RT&,
const D&,
bool hard_cast)
103 switch (process_structural_group_begin(GK_STRUCTURE, member_name,
GroupTraversal(reflect_group_begin(GK_STRUCTURE, member_name, &member_ref, &rt)))) {
104 case GT_TERMINATE :
return false;
107 return static_cast<D&
>(member_ref).D::self_reflect(*
this) && group_end(GK_STRUCTURE);
109 D& d =
static_cast<D&
>(member_ref);
110 return d.self_reflect(*
this) && group_end(GK_STRUCTURE);
112 default:
return true;
116 int reflect_array_begin(GroupKind group_kind,
const std::string& group_name,
void* group_ptr,
abst_reflection_traits* rt,
unsigned grp_size);
131 nesting_info(
GroupKind _group_kind = GK_NO_GROUP,
const std::string* _name = 0,
unsigned _idx = 0) : group_kind(_group_kind), name(_name), idx(_idx) {};
151 virtual int reflect_group_begin(
GroupKind group_kind,
const std::string& group_name,
void* group_ptr,
abst_reflection_traits* rt,
unsigned grp_size = -1);
154 virtual void reflect_group_end(
GroupKind group_kind);
161 abst_reflection_traits* return_traits,
const std::vector<abst_reflection_traits*>& param_value_traits) = 0;
170 virtual bool is_creative()
const;
179 template <
typename T>
180 bool reflect_member(
const std::string& member_name, T& member_ref,
bool hard_cast =
false);
189 template <
typename M>
190 bool reflect_method(
const std::string& method_name, M m);
192 template <
typename B>
193 bool reflect_base(B& base_ref);
195 template <
typename T,
unsigned n>
196 bool reflect_member(
const std::string& member_name, T (&member_ref)[n]);
198 template <
typename T>
199 bool reflect_member(
const std::string& member_name, std::vector<T>& member_ref);
204 template <
typename T>
205 bool reflect_member(
const std::string& member_name, T*& member_ref);
207 template <
typename T,
typename S>
208 bool reflect_array(
const std::string& member_name, T*& member_ref, S& size);
213 #ifndef REFLECT_TRAITS_WITH_DECLTYPE
214 template <
typename T, ReflectionTraitsKind K>
215 struct reflect_member_impl
217 template <
bool has_external,
typename RT>
218 struct reflect_impl {
219 static bool reflect(
reflection_handler* rh,
const std::string& member_name, T& member_ref,
const RT&,
bool hard_cast) {
224 template <
typename RT>
225 struct reflect_impl<true,RT> {
226 static bool reflect(reflection_handler* rh,
const std::string& member_name, T& member_ref,
const RT&,
bool hard_cast) {
228 return rh->self_reflect_member(member_name, member_ref, rt,
static_cast<typename RT::external_self_reflect_type&
>(member_ref), hard_cast);
231 template <
typename RT>
232 static bool reflect_RT(reflection_handler* rh,
const std::string& member_name, T& member_ref,
const RT& rt,
bool hard_cast) {
233 return reflect_impl<RT::has_external,RT>::reflect(rh, member_name, member_ref, rt, hard_cast);
235 static bool reflect(reflection_handler* rh,
const std::string& member_name, T& member_ref,
bool hard_cast) {
236 return reflect_RT(rh, member_name, member_ref, get_reflection_traits(member_ref), hard_cast);
240 template <
typename T>
struct reflect_member_impl<T,RTK_STD_TYPE>
242 static bool reflect(reflection_handler* rh,
const std::string& member_name, T& member_ref,
bool hard_cast) {
243 typename reflection_traits_info<T>::traits_type rt;
244 return rh->reflect_member_void(member_name, &member_ref, &rt);
248 template <
typename T, ReflectionTraitsKind K>
249 struct reflect_member_impl
251 static bool reflect(reflection_handler* rh,
const std::string& member_name, T& member_ref,
bool hard_cast) {
252 typename reflection_traits_info<T>::traits_type rt;
253 return rh->reflect_member_void(member_name, &member_ref, &rt);
257 template <
typename T>
struct reflect_member_impl<T,RTK_EXTERNAL_SELF_REFLECT>
259 static bool reflect(reflection_handler* rh,
const std::string& member_name, T& member_ref,
bool hard_cast) {
260 typename reflection_traits_info<T>::traits_type rt;
261 return rh->self_reflect_member(member_name, member_ref, rt,
static_cast<typename reflection_traits_info<T>::traits_type::external_self_reflect_type&
>(member_ref), hard_cast);
265 template <
typename T>
struct reflect_member_impl<T,RTK_SELF_REFLECT>
267 static bool reflect(reflection_handler* rh,
const std::string& member_name, T& member_ref,
bool hard_cast) {
268 typename reflection_traits_info<T>::traits_type rt;
269 return rh->self_reflect_member(member_name, member_ref, rt, member_ref, hard_cast);
273 template <
typename M,
typename R>
274 struct reflect_method_impl {
275 static bool reflect(reflection_handler* rh,
const std::string& method_name, M m)
277 static std::vector<abst_reflection_traits*> param_value_traits;
278 static method_interface_impl<M> mi(m);
280 method_parameter_traits_helper<0,cgv::type::traits::method_pointer<M>::nr_arguments,M>::fill_vector(param_value_traits);
281 typename reflection_traits_info<R>::traits_type rt;
282 return rh->reflect_method_void(method_name, &mi, &rt, param_value_traits);
285 template <
typename M>
286 struct reflect_method_impl<M,void> {
287 static bool reflect(reflection_handler* rh,
const std::string& method_name, M m)
289 static std::vector<abst_reflection_traits*> param_value_traits;
290 static method_interface_impl<M> mi(m);
292 method_parameter_traits_helper<0,cgv::type::traits::method_pointer<M>::nr_arguments,M>::fill_vector(param_value_traits);
293 return rh->reflect_method_void(method_name, &mi, 0, param_value_traits);
297 #ifndef REFLECT_TRAITS_WITH_DECLTYPE
298 template <
bool use_get,
typename B>
299 struct reflect_base_dispatch {
static bool reflect(reflection_handler* rh, B& base_ref) {
300 return rh->reflect_base_impl(base_ref,
typename reflection_traits_info<B>::traits_type()); } };
301 template <
typename B>
302 struct reflect_base_dispatch<true,B> {
static bool reflect(reflection_handler* rh, B& base_ref) {
303 return rh->reflect_base_impl(base_ref, get_reflection_traits(base_ref)); } };
305 template <
bool use_get,
typename T,
unsigned n>
306 struct reflect_const_array_dispatch {
static bool reflect(reflection_handler* rh,
const std::string& member_name, T (&member_ref)[n]) {
307 return rh->reflect_const_array_impl(member_name, member_ref,
typename reflection_traits_info<T>::traits_type()); } };
308 template <
typename T,
unsigned n>
309 struct reflect_const_array_dispatch<true,T,n> {
static bool reflect(reflection_handler* rh,
const std::string& member_name, T (&member_ref)[n]) {
310 return rh->reflect_const_array_impl(member_name, member_ref, get_reflection_traits(T())); } };
312 template <
bool use_get,
typename T>
313 struct reflect_vector_dispatch {
static bool reflect(reflection_handler* rh,
const std::string& member_name, std::vector<T>& member_ref) {
314 return rh->reflect_vector_impl(member_name, member_ref,
typename reflection_traits_info<T>::traits_type()); } };
315 template <
typename T>
316 struct reflect_vector_dispatch<true,T> {
static bool reflect(reflection_handler* rh,
const std::string& member_name, std::vector<T>& member_ref) {
317 return rh->reflect_vector_impl(member_name, member_ref, get_reflection_traits(T())); } };
322 template <
typename T>
325 #ifdef REFLECT_TRAITS_WITH_DECLTYPE
326 return detail::reflect_member_impl<T, reflection_traits_info<T>::kind>::reflect(
this, member_name, member_ref, hard_cast);
328 return detail::reflect_member_impl<T, reflection_traits_info<T>::kind>::reflect(
this, member_name, member_ref, hard_cast);
332 template <
typename M>
335 return detail::reflect_method_impl<M,typename cgv::type::traits::method_pointer<M>::return_type>::reflect(
this, method_name, m);
338 #ifdef REFLECT_TRAITS_WITH_DECLTYPE
339 template <
typename B>
344 template <
typename B,
typename RB>
345 bool reflection_handler::reflect_base_impl(B& base_ref,
const RB&)
350 case GT_TERMINATE :
return false;
352 default:
return true;
355 #ifndef REFLECT_TRAITS_WITH_DECLTYPE
356 template <
typename B>
359 return detail::reflect_base_dispatch<reflection_traits_info<B>::use_get,B>::reflect(
this,base_ref);
367 #ifdef REFLECT_TRAITS_WITH_DECLTYPE
368 template <
typename T,
unsigned n>
373 template <
typename T,
unsigned n,
typename RT>
374 bool reflection_handler::reflect_const_array_impl(
const std::string& member_name, T (&member_ref)[n],
const RT&)
379 if (grp_tra == GT_TERMINATE || grp_tra == GT_SKIP)
380 return grp_tra == GT_SKIP;
382 if (grp_tra == GT_COMPLETE) {
393 #ifndef REFLECT_TRAITS_WITH_DECLTYPE
394 template <
typename T,
unsigned n>
397 return detail::reflect_const_array_dispatch<reflection_traits_info<T>::use_get,T,n>::reflect(
this,member_name,member_ref);
401 #ifdef REFLECT_TRAITS_WITH_DECLTYPE
402 template <
typename T>
407 template <
typename T,
typename RT>
408 bool reflection_handler::reflect_vector_impl(
const std::string& member_name, std::vector<T>& member_ref,
const RT&)
412 int grp_tra =
reflect_array_begin(GK_VECTOR, member_name, &member_ref, &rt, (
unsigned)member_ref.size());
413 if (grp_tra == GT_TERMINATE || grp_tra == GT_SKIP)
414 return grp_tra == GT_SKIP;
416 if (grp_tra == GT_COMPLETE) {
417 unsigned size = (unsigned)member_ref.size();
419 if (member_ref.size() != size)
420 member_ref.resize(size);
431 #ifndef REFLECT_TRAITS_WITH_DECLTYPE
432 template <
typename T>
435 return detail::reflect_vector_dispatch<reflection_traits_info<T>::use_get,T>::reflect(
this, member_name, member_ref);
442 template <
typename T>
448 case GT_TERMINATE :
return false;
449 case GT_SKIP :
return true;
450 case GT_COMPLETE :
break;
452 std::cerr <<
"group traversal " <<
group_traversal_name(gt) <<
" not allowed on pointer group " << member_name <<
"!" << std::endl;
456 unsigned pointer_type = (member_ref == 0 ? 0 : 1);
457 unsigned pointer_type_tmp = pointer_type;
460 if (pointer_type_tmp != pointer_type) {
461 if (pointer_type != 0)
463 if (pointer_type_tmp == 0)
466 member_ref =
new T();
468 if (pointer_type_tmp != 0)
475 template <
typename T,
typename S>
480 if (grp_tra == GT_TERMINATE || grp_tra == GT_SKIP)
481 return grp_tra == GT_SKIP;
483 if (grp_tra == GT_COMPLETE) {
484 unsigned tmp_size = size;
486 if (size != tmp_size) {
488 member_ref =
new T[tmp_size];
490 for (
unsigned i=0; i<tmp_size && i < size; ++i)
491 member_ref[i] = tmp[i];
510 #include <cgv/config/lib_end.h>