summaryrefslogtreecommitdiff
path: root/src/bindings/cxx/eet_cxx/eet_register.hh
blob: b18da36f93cd497d2ee445a8d6c516f4cbf6232a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef EFL_EET_REGISTER_HH_
#define EFL_EET_REGISTER_HH_

#include <eet_type.hh>
#include <eet_composite.hh>

namespace efl { namespace eet {

template <typename, typename...> struct descriptor;

namespace _detail {

template <typename T>
struct member_type;

template <typename T, typename U>
struct member_type<T(U::*)>
{
  typedef T type;
};

template <typename T>
struct object_type;

template <typename T, typename U>
struct object_type<T(U::*)>
{
  typedef U type;
};

template <typename F, typename T, typename... Args>
struct member_info
{
  typedef F member_type;

  const char* name;
  F member;
  eet::descriptor<T, Args...> const* descriptor;
};

template <typename F>
struct member_info<F, void>
{
  typedef F member_type;

  const char* name;
  F member;
};

template <typename F, typename U, typename... Args>
void descriptor_type_register_impl
 (std::false_type
  , ::Eet_Data_Descriptor* cls
  , member_desc_info i
  , member_info<F, U, Args...> arg0
  , typename std::enable_if
  <
    !std::is_pointer<typename _detail::member_type<F>::type>::value
  >::type* = 0)
{
  // composition by value
  static_assert(std::is_member_object_pointer<F>::value, "");
  typedef typename _detail::member_type<F>::type member_type;
  static_assert(!std::is_pointer<member_type>::value, "");
  static_assert(std::is_same<member_type, U>::value, "");
  static_assert(std::is_pod<member_type>::value, "");

  _detail::descriptor_type_register_composite(cls, i, arg0.descriptor);
}

template <typename F, typename U, typename... Args>
void descriptor_type_register_impl
 (std::false_type
  , ::Eet_Data_Descriptor* cls
  , member_desc_info i
  , member_info<F, U, Args...> arg0
  , typename std::enable_if
  <
    std::is_pointer<typename _detail::member_type<F>::type>::value
  >::type* = 0)
{
  // composition by pointer
  static_assert(std::is_member_object_pointer<F>::value, "");
  typedef typename _detail::member_type<F>::type pointer_member_type;
  static_assert(std::is_pointer<pointer_member_type>::value, "");
  typedef typename std::remove_pointer<pointer_member_type>::type member_type;
  static_assert(std::is_same<member_type, U>::value, "");

  eet_data_descriptor_element_add
    (cls, i.name
     , EET_T_UNKNOW
     , EET_G_UNKNOWN
     , i.offset
     , 0
     , nullptr
     , const_cast<descriptor<U, Args...>*>(arg0.descriptor)->native_handle());
}

template <typename F>
void descriptor_type_register_impl
 (std::true_type, ::Eet_Data_Descriptor* cls
  , member_desc_info i
  , member_info<F, void>)
{
  static_assert(std::is_member_object_pointer<F>::value, "");
  typedef typename _detail::member_type<F>::type member_type;

  eet_data_descriptor_element_add(cls, i.name, _eet_type<member_type>::value, EET_G_UNKNOWN
                                  , i.offset, 0, nullptr, nullptr);
}

inline void descriptor_type_register( ::Eet_Data_Descriptor*, member_desc_info*)
{
}

template <typename F, typename D, typename... Args, typename... FArgs>
void descriptor_type_register( ::Eet_Data_Descriptor* cls, member_desc_info* i
                               , member_info<F, D, Args...> a0, FArgs... args)
{
  static_assert(std::is_member_object_pointer<F>::value, "");
  typedef typename _detail::member_type<F>::type member_type;

  _detail::descriptor_type_register_impl(is_eet_primitive<member_type>(), cls, *i, a0);
  _detail::descriptor_type_register(cls, ++i, args...);
}

} } }

#endif