-
Notifications
You must be signed in to change notification settings - Fork 1
/
mrubytypebinder.hpp
214 lines (189 loc) · 5.08 KB
/
mrubytypebinder.hpp
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#ifndef __MRUBYTYPEBINDER_HPP__
#define __MRUBYTYPEBINDER_HPP__
template<typename T>
struct TypeBinder
{
};
/* internally used datatypes */
template<>
struct TypeBinder<RClass*>
{
static mrb_value to_mrb_value(mrb_state* mrb, RClass* cls)
{
return mrb_class_path(mrb, cls);
}
static RClass* from_mrb_value(mrb_state* mrb, mrb_value val)
{
return mrb_class(mrb, val);
}
};
template<>
struct TypeBinder<RData*>
{
static mrb_value to_mrb_value(mrb_state* mrb, RData* data)
{
mrb_value val = {{ 0 }};
SET_OBJ_VALUE(val, data);
return val;
}
static RData* from_mrb_value(mrb_state* mrb, mrb_value val) { return RDATA(val); }
};
template<>
struct TypeBinder<RProc*>
{
static mrb_value to_mrb_value(mrb_state* mrb, RProc* data)
{
mrb_value val = {{ 0 }};
SET_OBJ_VALUE(val, data);
return val;
}
static RProc* from_mrb_value(mrb_state* mrb, mrb_value val)
{
return mrb_proc_ptr(val);
}
};
template<>
struct TypeBinder<mrb_sym>
{
static mrb_value to_mrb_value(mrb_state* mrb, mrb_sym sym) { return mrb_sym2str(mrb, sym); }
static mrb_sym from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_intern_str(mrb, val); }
};
/* public data types */
template<>
struct TypeBinder<bool>
{
static mrb_value to_mrb_value(mrb_state* mrb, bool b) { return mrb_bool_value(b); }
static bool from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_bool(val); }
};
template<>
struct TypeBinder<int>
{
static mrb_value to_mrb_value(mrb_state* mrb, int i) { return mrb_fixnum_value(i); }
static int from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_fixnum(val); }
};
template<>
struct TypeBinder<int64_t>
{
static mrb_value to_mrb_value(mrb_state* mrb, int64_t i) { return mrb_fixnum_value(i); }
static int64_t from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_fixnum(val); }
};
template<>
struct TypeBinder<float>
{
static mrb_value to_mrb_value(mrb_state* mrb, float f) { return mrb_float_value(mrb, f); }
static float from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_float(val); }
};
template<>
struct TypeBinder<double>
{
static mrb_value to_mrb_value(mrb_state* mrb, double f) { return mrb_float_value(mrb, f); }
static double from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_float(val); }
};
template<>
struct TypeBinder<size_t>
{
static mrb_value to_mrb_value(mrb_state* mrb, size_t i) { return mrb_fixnum_value(i); }
static size_t from_mrb_value(mrb_state* mrb, mrb_value val) { return mrb_fixnum(val); }
};
template<>
struct TypeBinder<std::string>
{
static mrb_value to_mrb_value(mrb_state* mrb, std::string str)
{
Arena arena(mrb);
{
return mrb_str_new(mrb, str.c_str(), str.size());
}
}
static std::string from_mrb_value(mrb_state* mrb, mrb_value val)
{
if (mrb_type(val) == MRB_TT_SYMBOL)
{
val = mrb_sym2str(mrb, mrb_symbol(val));
}
return std::string(RSTRING_PTR(val), RSTRING_LEN(val));
}
};
template<>
struct TypeBinder<const std::string>
{
static mrb_value to_mrb_value(mrb_state* mrb, const std::string str)
{
Arena arena(mrb);
{
return mrb_str_new(mrb, str.c_str(), str.size());
}
}
static std::string from_mrb_value(mrb_state* mrb, mrb_value val)
{
if (mrb_type(val) == MRB_TT_SYMBOL)
{
val = mrb_sym2str(mrb, mrb_symbol(val));
}
return std::string(RSTRING_PTR(val), RSTRING_LEN(val));
}
};
template<>
struct TypeBinder<const std::string&>
{
static mrb_value to_mrb_value(mrb_state* mrb, const std::string& str)
{
Arena arena(mrb);
{
return mrb_str_new(mrb, str.c_str(), str.size());
}
}
static std::string from_mrb_value(mrb_state* mrb, mrb_value val)
{
if (mrb_type(val) == MRB_TT_SYMBOL)
{
val = mrb_sym2str(mrb, mrb_symbol(val));
}
return std::string(RSTRING_PTR(val), RSTRING_LEN(val));
}
};
// TODO
// add specializations for
// Array type
// Hash type
// We might need more than just std::map or std::vector, since objects can be any type.
template<class TClass>
struct TypeBinder< NativeObject<TClass> >
{
static mrb_value to_mrb_value(mrb_state* mrb, NativeObject<TClass> obj)
{
Arena arena(mrb);
{
RClass* cls = mrb_class_get(mrb, obj.get_classname().c_str());
NativeObject<TClass>* objptr = new NativeObject<TClass>(obj);
RData* data = mrb_data_object_alloc(mrb, cls, objptr, objptr->get_type_ptr());
return TypeBinder<RData*>::to_mrb_value(mrb, data);
}
}
static NativeObject<TClass> from_mrb_value(mrb_state* mrb, mrb_value val)
{
if (mrb_type(val) == MRB_TT_DATA)
{
NativeObject<TClass>* thisptr = (NativeObject<TClass>*)DATA_PTR(val);
return *thisptr;
}
throw TypeError("Not a data type", "");
}
};
template<typename TFunc>
class Function;
template<typename TRet, typename ... TArgs>
class Function<TRet(TArgs...)>;
template<typename TRet, typename ... TArgs>
struct TypeBinder< Function<TRet(TArgs...)> >
{
static mrb_value to_mrb_value(mrb_state* mrb, Function<TRet(TArgs...)> func)
{
throw NotImplementedError("Not implemented", "");
}
static Function<TRet(TArgs...)> from_mrb_value(mrb_state* mrb, mrb_value val)
{
return Function<TRet(TArgs...)>(mrb, TypeBinder<RProc*>::from_mrb_value(mrb, val));
}
};
#endif // __MRUBYTYPEBINDER_HPP__