forked from MacRuby/MacRuby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
array.h
150 lines (133 loc) · 3.87 KB
/
array.h
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
/*
* MacRuby Array.
*
* This file is covered by the Ruby license. See COPYING for more details.
*
* Copyright (C) 2010, Apple Inc. All rights reserved.
*/
#ifndef __ARRAY_H_
#define __ARRAY_H_
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct {
struct RBasic basic;
size_t beg;
size_t len;
size_t cap;
VALUE *elements;
} rb_ary_t;
#define RARY(x) ((rb_ary_t *)x)
static inline bool
rb_klass_is_rary(VALUE klass)
{
do {
if (klass == rb_cRubyArray) {
return true;
}
if (klass == rb_cNSArray) {
return false;
}
klass = RCLASS_SUPER(klass);
}
while (klass != 0);
return false;
}
#define IS_RARY(x) (rb_klass_is_rary(*(VALUE *)x))
static inline void
rary_modify(VALUE ary)
{
const long mask = RBASIC(ary)->flags;
if ((mask & FL_FREEZE) == FL_FREEZE) {
rb_raise(rb_eRuntimeError, "can't modify frozen/immutable array");
}
if ((mask & FL_TAINT) == FL_TAINT && rb_safe_level() >= 4) {
rb_raise(rb_eSecurityError, "Insecure: can't modify array");
}
}
static inline VALUE
rary_elt(VALUE ary, size_t idx)
{
//assert(idx < RARY(ary)->len);
return RARY(ary)->elements[RARY(ary)->beg + idx];
}
static inline void
rary_elt_set(VALUE ary, size_t idx, VALUE item)
{
//assert(idx < ary->len);
GC_WB(&RARY(ary)->elements[RARY(ary)->beg + idx], item);
}
static inline VALUE *
rary_ptr(VALUE ary)
{
return &RARY(ary)->elements[RARY(ary)->beg];
}
static inline VALUE
rary_entry(VALUE ary, long offset)
{
const long n = RARY(ary)->len;
if (n == 0) {
return Qnil;
}
if (offset < 0) {
offset += n;
}
if (offset < 0 || n <= offset) {
return Qnil;
}
return rary_elt(ary, offset);
}
static inline void
rb_ary_modify(VALUE ary)
{
if (IS_RARY(ary)) {
rary_modify(ary);
}
}
static inline VALUE
to_ary(VALUE ary)
{
return rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
}
VALUE rary_dup(VALUE ary, SEL sel);
VALUE rary_clear(VALUE ary, SEL sel);
VALUE rary_reverse_bang(VALUE ary, SEL sel);
VALUE rary_includes(VALUE ary, SEL sel, VALUE item);
VALUE rary_delete(VALUE ary, SEL sel, VALUE item);
VALUE rary_delete_at(VALUE ary, SEL sel, VALUE pos);
VALUE rary_pop(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_shift(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_aref(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_plus(VALUE x, SEL sel, VALUE y);
VALUE rary_push_m(VALUE ary, SEL sel, VALUE item);
VALUE rary_concat_m(VALUE x, SEL sel, VALUE y);
VALUE rary_last(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_unshift(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_each(VALUE ary, SEL sel);
VALUE rary_sort(VALUE ary, SEL sel);
VALUE rary_sort_bang(VALUE ary, SEL sel);
void rary_store(VALUE ary, long idx, VALUE item);
VALUE rary_subseq(VALUE ary, long beg, long len);
void rary_insert(VALUE ary, long idx, VALUE val);
// Shared implementations.
VALUE rary_join(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_zip(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_transpose(VALUE ary, SEL sel);
VALUE rary_fill(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_cmp(VALUE ary1, SEL sel, VALUE ary2);
VALUE rary_assoc(VALUE ary, SEL sel, VALUE key);
VALUE rary_rassoc(VALUE ary, SEL sel, VALUE value);
VALUE rary_flatten(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_flatten_bang(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_product(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_combination(VALUE ary, SEL sel, VALUE num);
VALUE rary_permutation(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_cycle(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_sample(VALUE ary, SEL sel, int argc, VALUE *argv);
VALUE rary_diff(VALUE ary1, SEL sel, VALUE ary2);
VALUE rary_and(VALUE ary1, SEL sel, VALUE ary2);
VALUE rary_or(VALUE ary1, SEL sel, VALUE ary2);
#if defined(__cplusplus)
} // extern "C"
#endif
#endif // __ARRAY_H_