15#include "internal/error.h"
20#include "internal/symbol.h"
35static ID id_members, id_back_members, id_keyword_init;
62 return struct_ivar_get(klass, id_keyword_init);
68 VALUE members = struct_ivar_get(klass, id_members);
73 if (!RB_TYPE_P(members,
T_ARRAY)) {
99struct_member_pos_probe(
long prev,
long mask)
109 const long members_length =
RARRAY_LEN(members);
115 long i, j,
mask = 64;
124 for (i=0; i < members_length; i++) {
127 j = struct_member_pos_ideal(
name,
mask);
135 j = struct_member_pos_probe(j,
mask);
164 "struct size differs (%ld required %ld given)",
167 for (j = 0; j <
mask; j++) {
180 j = struct_member_pos_ideal(
name,
mask);
189 j = struct_member_pos_probe(j,
mask);
194rb_struct_s_members_m(
VALUE klass)
213rb_struct_members_m(
VALUE obj)
222 int i = struct_member_pos(obj, slot);
226 rb_name_err_raise(
"`%1$s' is not a struct member", obj,
ID2SYM(
id));
242#define N_REF_FUNC numberof(ref_func)
258rb_struct_modify(
VALUE s)
264anonymous_struct(
VALUE klass)
281 rb_name_err_raise(
"identifier %1$s needs to be constant",
298 if (i < 0 || i >=
RSTRUCT_LEN(s)) invalid_struct_pos(s, idx);
305 long i = struct_pos_num(self, idx);
312 long i = struct_pos_num(self, idx);
313 rb_struct_modify(self);
341rb_struct_s_inspect(
VALUE klass)
355 members = struct_set_members(nstr, members);
363 for (i=0; i<
len; i++) {
372 define_aref_method(nstr,
sym, off);
383 return struct_alloc(klass);
387struct_make_members_list(va_list ar)
393 RBASIC_CLEAR_CLASS(list);
395 while ((mem = va_arg(ar,
char*)) != 0) {
403 RBASIC_CLEAR_CLASS(ary);
422 klass = anonymous_struct(super);
425 struct_set_members(klass, members);
444 members = struct_make_members_list(ar);
447 return struct_define_without_accessor(outer, class_name, super, alloc, members);
457 members = struct_make_members_list(ar);
460 return struct_define_without_accessor(0, class_name, super, alloc, members);
470 ary = struct_make_members_list(ar);
475 return setup_struct(st, ary);
485 ary = struct_make_members_list(ar);
573 static ID keyword_ids[1];
575 if (!keyword_ids[0]) {
576 keyword_ids[0] =
rb_intern(
"keyword_init");
579 if (keyword_init ==
Qundef) {
586 RBASIC_CLEAR_CLASS(rest);
589 for (i=0; i<
argc; i++) {
600 RBASIC_CLEAR_CLASS(rest);
603 st = anonymous_struct(klass);
606 st = new_struct(
name, klass);
608 setup_struct(st, rest);
618num_members(
VALUE klass)
621 members = struct_ivar_get(klass, id_members);
622 if (!RB_TYPE_P(members,
T_ARRAY)) {
642 int i = rb_struct_pos(args->
self, &
key);
650 rb_struct_modify(args->
self);
662 rb_struct_modify(
self);
663 n = num_members(klass);
671 arg.unknown_keywords =
Qnil;
673 if (arg.unknown_keywords !=
Qnil) {
682 for (i=0; i<
argc; i++) {
701struct_heap_alloc(
VALUE st,
size_t len)
706 RSTRUCT_TRANSIENT_SET(st);
710 RSTRUCT_TRANSIENT_UNSET(st);
715#if USE_TRANSIENT_HEAP
719 if (RSTRUCT_TRANSIENT_P(obj)) {
720 const VALUE *old_ptr = rb_struct_const_heap_ptr(obj);
729 new_ptr = struct_heap_alloc(obj,
len);
732 RSTRUCT(obj)->as.heap.ptr = new_ptr;
738struct_alloc(
VALUE klass)
743 n = num_members(klass);
746 RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
751 st->as.heap.ptr = struct_heap_alloc((
VALUE)st, n);
775 mem = RARRAY_PTR(tmpargs[0]);
777 va_start(args, klass);
778 for (i=0; i<
size; i++) {
779 mem[i] = va_arg(args,
VALUE);
812rb_struct_each(
VALUE s)
843rb_struct_each_pair(
VALUE s)
875 if (
recur || first !=
'#') {
885 for (i=0; i<
len; i++) {
892 else if (first !=
'#') {
920rb_struct_inspect(
VALUE s)
938rb_struct_to_a(
VALUE s)
961rb_struct_to_h(
VALUE s)
979rb_struct_deconstruct_keys(
VALUE s,
VALUE keys)
985 return rb_struct_to_h(s);
989 "wrong argument type %"PRIsVALUE" (expected Array or nil)",
999 int i = rb_struct_pos(s, &
key);
1033 return struct_member_pos(s, idx);
1035 else if (RB_TYPE_P(idx,
T_STRING)) {
1037 if (
NIL_P(idx))
return -1;
1038 return struct_member_pos(s, idx);
1051 else if (
len <= i) {
1074 rb_name_err_raise(
"no member '%1$s' in struct", s, idx);
1098 int i = rb_struct_pos(s, &idx);
1099 if (i < 0) invalid_struct_pos(s, idx);
1125 int i = rb_struct_pos(s, &idx);
1126 if (i < 0) invalid_struct_pos(s, idx);
1127 rb_struct_modify(s);
1138 return rb_struct_lookup_default(s, idx,
Qnil);
1144 int i = rb_struct_pos(s, &idx);
1145 if (i < 0)
return notfound;
1150struct_entry(
VALUE s,
long n)
1218 for (i=0; i<
len; i++) {
1242 if (s == s2)
return Qtrue;
1246 rb_bug(
"inconsistent struct");
1262rb_struct_hash(
VALUE s)
1270 for (i = 0; i <
len; i++) {
1285 for (i=0; i<
len; i++) {
1303 if (s == s2)
return Qtrue;
1307 rb_bug(
"inconsistent struct");
1431 id_back_members =
rb_intern(
"__members_back__");
1432 id_keyword_init =
rb_intern(
"__keyword_init__");
void rb_mem_clear(VALUE *mem, long size)
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE(*func)(VALUE, long))
VALUE rb_ary_dup(VALUE ary)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_entry(VALUE ary, long offset)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
VALUE rb_ary_join(VALUE ary, VALUE sep)
#define FUNC_MINIMIZED(x)
#define UNREACHABLE_RETURN
#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity, _compiler)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_method_id(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
char str[HTML_ESCAPE_MAX_LEN+1]
#define RSTRING_PTR(string)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_class_new(VALUE super)
Creates a new class.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_class_inherited(VALUE super, VALUE klass)
Calls Class::inherited.
VALUE rb_make_metaclass(VALUE obj, VALUE unused)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_bug(const char *fmt,...)
VALUE rb_ident_hash_new(void)
void rb_warn(const char *fmt,...)
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
VALUE rb_cObject
Object class.
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
VALUE rb_class_new_instance_pass_kw(int, const VALUE *, VALUE)
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
VALUE rb_obj_class(VALUE)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_equal(VALUE, VALUE)
This function is an optimized version of calling #==.
VALUE rb_hash_set_pair(VALUE hash, VALUE arg)
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_hash_new_with_size(st_index_t size)
VALUE rb_hash_keys(VALUE hash)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Defines RBIMPL_HAS_BUILTIN.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
#define UNLIMITED_ARGUMENTS
#define OBJ_INIT_COPY(obj, orig)
#define rb_hash_uint(h, i)
st_index_t rb_hash_start(st_index_t)
VALUE rb_str_append(VALUE, VALUE)
#define rb_str_cat_cstr(buf, str)
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
VALUE rb_class_name(VALUE)
int rb_const_defined_at(VALUE, ID)
VALUE rb_class_path(VALUE)
VALUE rb_mod_remove_const(VALUE, VALUE)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
VALUE rb_mod_module_eval(int, const VALUE *, VALUE)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
void rb_undef_alloc_func(VALUE)
VALUE(* rb_alloc_func_t)(VALUE)
VALUE rb_check_symbol(volatile VALUE *namep)
Returns Symbol for the given name if it is interned already, or nil.
ID rb_intern(const char *)
VALUE rb_to_symbol(VALUE name)
Internal header for Class.
Internal header for Hash.
Internal header for Object.
Internal header for Proc.
int rb_block_pair_yield_optimizable(void)
Internal header for Struct.
@ RSTRUCT_EMBED_LEN_SHIFT
int rb_is_attrset_sym(VALUE sym)
int rb_is_const_name(VALUE name)
#define rb_sym_intern_ascii_cstr(...)
VALUE rb_yield_values(int n,...)
#define MEMCPY(p1, p2, type, n)
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
#define RARRAY_CONST_PTR(s)
#define RARRAY_AREF(a, i)
#define RGENGC_WB_PROTECTED_STRUCT
VALUE rb_str_to_str(VALUE)
VALUE rb_struct_define_under(VALUE outer, const char *name,...)
const rb_iseq_t * rb_method_for_self_aset(VALUE name, VALUE arg, const struct rb_builtin_function *func)
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc,...)
VALUE rb_struct_new(VALUE klass,...)
VALUE rb_struct_getmember(VALUE obj, ID id)
VALUE rb_struct_init_copy(VALUE copy, VALUE s)
VALUE rb_struct_size(VALUE s)
VALUE rb_struct_initialize(VALUE self, VALUE values)
VALUE rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc,...)
VALUE rb_struct_define(const char *name,...)
VALUE rb_struct_alloc(VALUE klass, VALUE values)
VALUE rb_struct_aset(VALUE s, VALUE idx, VALUE val)
VALUE rb_struct_members(VALUE s)
VALUE rb_struct_alloc_noinit(VALUE klass)
VALUE rb_struct_s_members(VALUE klass)
VALUE rb_struct_lookup(VALUE s, VALUE idx)
VALUE rb_struct_aref(VALUE s, VALUE idx)
const rb_iseq_t * rb_method_for_self_aref(VALUE name, VALUE arg, const struct rb_builtin_function *func)
VALUE rb_struct_s_keyword_init(VALUE klass)
struct rb_iseq_constant_body * body
#define rb_struct_transient_heap_evacuate(x, y)
#define rb_transient_heap_alloc(o, s)