mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-set: update Set class to use struct RSet not struct RData
This commit is contained in:
@@ -164,7 +164,7 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
|
||||
f(MRB_TT_RATIONAL, struct RRational, "Rational") \
|
||||
f(MRB_TT_BIGINT, struct RBigint, "Integer") \
|
||||
f(MRB_TT_BACKTRACE, struct RBacktrace, "backtrace") \
|
||||
f(MRB_TT_SET, struct RData, "Set")
|
||||
f(MRB_TT_SET, struct RSet, "Set")
|
||||
|
||||
enum mrb_vtype {
|
||||
#define MRB_VTYPE_DEFINE(tt, type, name) tt,
|
||||
|
||||
+16
-33
@@ -19,6 +19,11 @@
|
||||
KHASH_DECLARE(set, mrb_value, char, FALSE)
|
||||
KHASH_DEFINE(set, mrb_value, char, FALSE, mrb_obj_hash_code, mrb_eql)
|
||||
|
||||
struct RSet {
|
||||
MRB_OBJECT_HEADER;
|
||||
khash_t(set) *kh;
|
||||
};
|
||||
|
||||
static void
|
||||
set_copy_elements(mrb_state *mrb, khash_t(set) *target_kh, khash_t(set) *source_kh)
|
||||
{
|
||||
@@ -31,48 +36,28 @@ set_copy_elements(mrb_state *mrb, khash_t(set) *target_kh, khash_t(set) *source_
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_KHASH_IV MRB_SYM(khash)
|
||||
|
||||
static void
|
||||
set_free(mrb_state *mrb, void *ptr)
|
||||
{
|
||||
khash_t(set) *kh = (khash_t(set)*)ptr;
|
||||
if (kh) {
|
||||
kh_destroy(set, mrb, kh);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct mrb_data_type set_data_type = {
|
||||
"Set", set_free
|
||||
};
|
||||
|
||||
#define mrb_set_ptr(o) ((struct RSet*)mrb_obj_ptr(o))
|
||||
static void
|
||||
set_set_khash(mrb_state *mrb, mrb_value self, khash_t(set) *kh)
|
||||
{
|
||||
/* When MRB_TT_SET is used, RData's type field is not strictly necessary */
|
||||
/* for type checking if mrb_type() is MRB_TT_SET. However, it can still hold */
|
||||
/* the dfree function if we choose to use it via a generic RData path. */
|
||||
/* For now, keeping it for set_free via set_data_type if needed. */
|
||||
((struct RData*)mrb_obj_ptr(self))->type = &set_data_type;
|
||||
((struct RData*)mrb_obj_ptr(self))->data = kh;
|
||||
mrb_check_type(mrb, self, MRB_TT_SET);
|
||||
struct RSet *set = mrb_set_ptr(self);
|
||||
set->kh = kh;
|
||||
}
|
||||
|
||||
static khash_t(set) *
|
||||
set_get_khash(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_assert(mrb_type(self) == MRB_TT_SET);
|
||||
return (khash_t(set)*)((struct RData*)mrb_obj_ptr(self))->data;
|
||||
mrb_check_type(mrb, self, MRB_TT_SET);
|
||||
return mrb_set_ptr(self)->kh;
|
||||
}
|
||||
|
||||
#ifdef MRB_USE_SET
|
||||
/* Mark function for Set instances */
|
||||
size_t
|
||||
mrb_gc_mark_set(mrb_state *mrb, struct RBasic *obj)
|
||||
{
|
||||
struct RData *d = (struct RData*)obj;
|
||||
if (!d->data) return 0;
|
||||
|
||||
khash_t(set) *kh = (khash_t(set)*)d->data;
|
||||
struct RSet *s = (struct RSet*)obj;
|
||||
khash_t(set) *kh = s->kh;
|
||||
if (!kh) return 0;
|
||||
|
||||
KHASH_FOREACH(mrb, kh, k) {
|
||||
@@ -86,16 +71,14 @@ mrb_gc_mark_set(mrb_state *mrb, struct RBasic *obj)
|
||||
void
|
||||
mrb_gc_free_set(mrb_state *mrb, struct RBasic *obj)
|
||||
{
|
||||
struct RData *d = (struct RData*)obj;
|
||||
if (d->data) {
|
||||
khash_t(set) *kh = (khash_t(set)*)d->data;
|
||||
struct RSet *s = (struct RSet*)obj;
|
||||
if (s->kh) {
|
||||
khash_t(set) *kh = s->kh;
|
||||
if (kh) {
|
||||
kh_destroy(set, mrb, kh);
|
||||
}
|
||||
}
|
||||
mrb_gc_free_iv(mrb, (struct RObject*)obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Helper function to check if a value is a Set and return a boolean result */
|
||||
static mrb_bool
|
||||
|
||||
Reference in New Issue
Block a user