GCC Code Coverage Report


./
File: mrubyclass.hpp
Date: 2024-05-21 01:02:25
Lines:
116/124
93.5%
Functions:
59/66
89.4%
Branches:
66/152
43.4%

Line Branch Exec Source
1 #ifndef __MRUBYCLASS_HPP__
2 #define __MRUBYCLASS_HPP__
3
4 template<class TClass>
5 class Class : public Module
6 {
7 template <typename ... TConstructorArgs>
8 5 static mrb_value constructor(mrb_state* mrb, mrb_value self)
9 {
10 5 START_HANDLE_ERROR
11 {
12 5 RClass* cls = TypeBinder<RClass*>::from_mrb_value(mrb, self);
13
14
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 mrb_sym nsym = mrb_intern_lit(mrb, "__classname__");
15
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 mrb_value nval = mrb_obj_iv_get(mrb, (struct RObject*)cls, nsym);
16
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 std::string str = TypeBinder<std::string>::from_mrb_value(mrb, nval);
17
18 5 std::function<std::shared_ptr<TClass>(TConstructorArgs...)> func =
19 10 [=](TConstructorArgs... params) -> std::shared_ptr<TClass>
20 {
21 5 return std::make_shared<TClass>(params...);
22 };
23
24
25 mrb_value* args;
26 5 size_t argc = 0;
27
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 mrb_get_args(mrb, "*", &args, &argc);
28
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (argc != sizeof...(TConstructorArgs))
30 {
31 HANDLE_ERROR_AND_EXIT error_argument_count(mrb, str, "initialize", argc, sizeof...(TConstructorArgs));
32 }
33
34
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 auto curried = curry(func);
35 5 std::shared_ptr<TClass> instance = nullptr;
36 try
37 {
38
3/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1 times.
6 instance = func_caller<0, std::shared_ptr<TClass>, TConstructorArgs...>(mrb, curried, args);
39 }
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 catch (const RubyException &e)
41 {
42
3/6
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 HANDLE_ERROR_AND_EXIT mrb_exc_new(mrb, E_RUNTIME_ERROR, e.what(), strlen(e.what()));
43 }
44
45
2/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
4 NativeObject<TClass>* ptr = new NativeObject<TClass>(str, instance);
46
47 4 DATA_TYPE(self) = ptr->get_type_ptr();
48 4 DATA_PTR(self) = ptr;
49 4 return self;
50 8 }
51
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 END_HANDLE_ERROR
52 }
53
54 14 static mrb_value default_constructor(mrb_state* mrb, mrb_value self)
55 {
56 14 START_HANDLE_ERROR
57 {
58 14 RClass* cls = TypeBinder<RClass*>::from_mrb_value(mrb, self);
59
60
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
14 mrb_sym nsym = mrb_intern_lit(mrb, "__classname__");
61
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
14 mrb_value nval = mrb_obj_iv_get(mrb, (struct RObject*)cls, nsym);
62
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
14 std::string str = TypeBinder<std::string>::from_mrb_value(mrb, nval);
63
64 mrb_value* args;
65 14 size_t argc = 0;
66
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
14 mrb_get_args(mrb, "*", &args, &argc);
67
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
14 if (argc != 0)
69 {
70 HANDLE_ERROR_AND_EXIT error_argument_count(mrb, str, "initialize", argc, 0);
71 }
72
73 14 std::shared_ptr<TClass> instance = nullptr;
74 try
75 {
76
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
14 instance = std::make_shared<TClass>();
77 }
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 catch (const RubyException &e)
79 {
80
3/6
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 HANDLE_ERROR_AND_EXIT mrb_exc_new(mrb, E_RUNTIME_ERROR, e.what(), strlen(e.what()));
81 }
82
83
2/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
13 NativeObject<TClass>* ptr = new NativeObject<TClass>(str, instance);
84
85 13 DATA_TYPE(self) = ptr->get_type_ptr();
86 13 DATA_PTR(self) = ptr;
87
88 13 return self;
89 15 }
90
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 END_HANDLE_ERROR
91 }
92
93 1 static mrb_value error_constructor_closed(mrb_state *mrb, mrb_value class_name) {
94 1 mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' cannot be created with new",
95 class_name);
96 return mrb_nil_value();
97 }
98
99 1 static mrb_value closed_constructor(mrb_state* mrb, mrb_value self)
100 {
101 1 return error_constructor_closed(mrb, self);
102 }
103 public:
104
105 template <typename ... TConstructorArgs>
106 7 Class(std::shared_ptr<mrb_state> mrb, const std::string& name, RClass* cls, void(*)(TConstructorArgs...)) :
107
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 Module(mrb, name, cls)
108 {
109 7 MRB_SET_INSTANCE_TT(cls, MRB_TT_DATA);
110
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 mrb_define_method(mrb.get(), cls, "initialize", constructor<TConstructorArgs...>, MRB_ARGS_ARG(sizeof...(TConstructorArgs),0));
111 7 }
112
113 34 Class(std::shared_ptr<mrb_state> mrb, const std::string& name, RClass* cls, void(*)(void)) :
114
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
34 Module(mrb, name, cls)
115 {
116 34 MRB_SET_INSTANCE_TT(cls, MRB_TT_DATA);
117
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
34 mrb_define_method(mrb.get(), cls, "initialize", default_constructor, MRB_ARGS_ARG(0, 0));
118 34 }
119
120 5 Class(std::shared_ptr<mrb_state> mrb, const std::string& name, RClass* cls) :
121
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
5 Module(mrb, name, cls)
122 {
123 5 MRB_SET_INSTANCE_TT(cls, MRB_TT_DATA);
124
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
5 mrb_define_method(mrb.get(), cls, "initialize", closed_constructor, MRB_ARGS_ARG(0, 0));
125 5 }
126
127 84 ~Class()
128 {
129
130 84 }
131
132
133 template<typename TVal>
134 2 static mrb_value mruby_member_setter(mrb_state* mrb, mrb_value self)
135 {
136 try
137 {
138 typedef TVal TClass::* memptr_t;
139 2 RClass* cls = TypeBinder<RClass*>::from_mrb_value(mrb, self);
140
141 mrb_value* args;
142 2 size_t argc = 0;
143
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_get_args(mrb, "*", &args, &argc);
144
145
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_value kernel_val = TypeBinder<RClass*>::to_mrb_value(mrb, mrb->kernel_module);
146
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_value nval = mrb_funcall(mrb, kernel_val, "__method__", 0);
147
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 std::string name = TypeBinder<std::string>::from_mrb_value(mrb, nval);
148
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 std::string ptr_name = "__allocated_memptr__" + name.substr(0, name.length()-1);
149
150
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 mrb_sym mem_ptr_sym = mrb_intern_cstr(mrb, ptr_name.c_str());
151
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_value mem_ptr_holder = mrb_mod_cv_get(mrb, cls, mem_ptr_sym);
152
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (argc != 1)
154 {
155 std::string class_name = TypeBinder<std::string>::from_mrb_value(mrb, self);
156 throw error_argument_count(mrb, class_name, name, argc, 1);
157 }
158
159
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 NativeObject<memptr_t> obj = TypeBinder< NativeObject<memptr_t> >::from_mrb_value(mrb, mem_ptr_holder);
160
161 2 memptr_t* ptr = obj.get_instance();
162 2 NativeObject<TClass>* thisptr = (NativeObject<TClass>*)DATA_PTR(self);
163
164 2 thisptr->get_instance()->**ptr = TypeBinder<TVal>::from_mrb_value(mrb, *args);
165 2 }
166 catch(mrb_value exc)
167 {
168 mrb_exc_raise(mrb, exc);
169 }
170 2 return mrb_nil_value();
171 }
172
173 template<typename TVal>
174 2 static mrb_value mruby_member_getter(mrb_state* mrb, mrb_value self)
175 {
176 typedef TVal TClass::* memptr_t;
177 2 RClass* cls = TypeBinder<RClass*>::from_mrb_value(mrb, self);
178
179
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_value kernel_val = TypeBinder<RClass*>::to_mrb_value(mrb, mrb->kernel_module);
180
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_value nval = mrb_funcall(mrb, kernel_val, "__method__", 0);
181
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 std::string name = TypeBinder<std::string>::from_mrb_value(mrb, nval);
182
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 std::string ptr_name = "__allocated_memptr__" + name;
183
184
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 mrb_sym mem_ptr_sym = mrb_intern_cstr(mrb, ptr_name.c_str());
185
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mrb_value mem_ptr_holder = mrb_mod_cv_get(mrb, cls, mem_ptr_sym);
186
187
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 NativeObject<memptr_t> obj = TypeBinder< NativeObject<memptr_t> >::from_mrb_value(mrb, mem_ptr_holder);
188
189 2 memptr_t* ptr = obj.get_instance();
190 2 NativeObject<TClass>* thisptr = (NativeObject<TClass>*)DATA_PTR(self);
191
192 4 return TypeBinder<TVal>::to_mrb_value(mrb, thisptr->get_instance()->**ptr);
193 2 }
194
195 template<typename TVal>
196 9 void create_accessor(const std::string& name, TVal TClass::* var, RClass* module_class)
197 {
198 typedef TVal TClass::* memptr_t;
199
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 std::string ptr_name = "__allocated_memptr__" + name;
200
1/2
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
9 mrb_sym mem_ptr_sym = mrb_intern_cstr(mrb.get(), ptr_name.c_str());
201
202 9 function_definer_t define_function_method = mrb_define_method;
203
204
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 memptr_t* ptr = new memptr_t;
205 9 *ptr = var;
206
3/6
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
27 NativeObject<memptr_t> obj("Object", std::shared_ptr<memptr_t>(ptr));
207
208
3/6
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 9 times.
✗ Branch 10 not taken.
9 mrb_mod_cv_set(
209 mrb.get(),
210 module_class,
211 mem_ptr_sym,
212 TypeBinder< NativeObject<memptr_t> >::to_mrb_value(mrb.get(), obj));
213
214
1/2
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
9 define_function_method(
215 mrb.get(),
216 module_class,
217 name.c_str(),
218 mruby_member_getter<TVal>,
219 MRB_ARGS_REQ(0));
220
221
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
9 define_function_method(
222 mrb.get(),
223 module_class,
224 (name + "=").c_str(),
225 mruby_member_setter<TVal>,
226 MRB_ARGS_REQ(1));
227 9 }
228
229 template<typename TVar>
230 4 void bind_instance_variable(const std::string& name, TVar TClass::* var)
231 {
232 4 create_accessor(name, var, cls);
233 4 }
234
235 #ifndef _MSC_VER
236 template<typename TC2, typename TVar>
237 5 void bind_instance_variable(const std::string& name, TVar TC2::* var)
238 {
239 static_assert(std::is_base_of<TC2, TClass>::value, "You must provide a member variable that is somewhere up the inheritance chain of this class");
240 5 create_accessor(name, (TVar TClass::*)(var), cls);
241 5 }
242 #endif
243
244 template<typename TRet, typename ... TArgs>
245 20 void bind_instance_method(const std::string& name, TRet(TClass::*func)(TArgs...))
246 {
247 20 create_function(name, func, cls, mrb_define_method);
248 20 }
249
250 template<typename TRet, typename ... TArgs>
251 void bind_instance_method(const std::string& name, TRet(TClass::*func)(TArgs...) const)
252 {
253 create_function(name, func, cls, mrb_define_method);
254 }
255
256 #ifndef _MSC_VER
257 template<typename TC2, typename TRet, typename ... TArgs>
258 2 void bind_instance_method(const std::string& name, TRet(TC2::*func)(TArgs...))
259 {
260 static_assert(std::is_base_of<TC2, TClass>::value, "You must provide a member function that is somewhere in the inheritance chain of this class");
261 typedef TRet(TClass::*TTarget)(TArgs...);
262 2 create_function(name, (TTarget)func, cls, mrb_define_method);
263 2 }
264 #endif
265 };
266
267 #endif // __MRUBYCLASS_HPP__
268