- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/src/array.c
r321 r331 1 #include "mruby.h"2 #include "mruby/value.h"3 #include "mruby/array.h"4 #include "mruby/range.h"5 #include "mruby/hash.h"1 #include <mruby.h> 2 #include <mruby/value.h> 3 #include <mruby/array.h> 4 #include <mruby/range.h> 5 #include <mruby/hash.h> 6 6 7 7 /* … … 132 132 if (mrb_nil_p(v)) { 133 133 mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)", 134 mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, RARRAY_PTR(ary)[i])),134 mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, ary_elt(ary, i))), 135 135 mrb_fixnum_value(i) 136 136 ); … … 150 150 } 151 151 152 /* 153 * call-seq: 154 * ary.slice!(index) -> obj or nil 155 * ary.slice!(start, length) -> new_ary or nil 156 * ary.slice!(range) -> new_ary or nil 157 * 158 * Deletes the element(s) given by an +index+ (optionally up to +length+ 159 * elements) or by a +range+. 160 * 161 * Returns the deleted object (or objects), or +nil+ if the +index+ is out of 162 * range. 163 * 164 * a = [ "a", "b", "c" ] 165 * a.slice!(1) #=> "b" 166 * a #=> ["a", "c"] 167 * a.slice!(-1) #=> "c" 168 * a #=> ["a"] 169 * a.slice!(100) #=> nil 170 * a #=> ["a"] 171 */ 172 173 static mrb_value 174 mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) 175 { 176 struct RArray *a = mrb_ary_ptr(self); 177 mrb_int i, j, k, len; 178 mrb_value index; 179 mrb_value val; 180 mrb_value *ptr; 181 mrb_value ary; 182 183 mrb_ary_modify(mrb, a); 184 185 if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { 186 switch (mrb_type(index)) { 187 case MRB_TT_RANGE: 188 if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) { 189 goto delete_pos_len; 190 } 191 else { 192 return mrb_nil_value(); 193 } 194 case MRB_TT_FIXNUM: 195 val = mrb_funcall(mrb, self, "delete_at", 1, index); 196 return val; 197 default: 198 val = mrb_funcall(mrb, self, "delete_at", 1, index); 199 return val; 200 } 201 } 202 203 i = mrb_fixnum(index); 204 delete_pos_len: 205 if (i < 0) i += a->len; 206 if (i < 0 || a->len < i) return mrb_nil_value(); 207 if (len < 0) return mrb_nil_value(); 208 if (a->len == i) return mrb_ary_new(mrb); 209 if (len > a->len - i) len = a->len - i; 210 211 ary = mrb_ary_new_capa(mrb, len); 212 213 for (j = i, k = 0; k < len; ++j, ++k) { 214 mrb_ary_push(mrb, ary, a->ptr[j]); 215 } 216 217 ptr = a->ptr + i; 218 for (j = i; j < a->len - len; ++j) { 219 *ptr = *(ptr+len); 220 ++ptr; 221 } 222 223 mrb_ary_resize(mrb, self, a->len - len); 224 return ary; 225 } 226 152 227 void 153 228 mrb_mruby_array_ext_gem_init(mrb_state* mrb) … … 160 235 mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY()); 161 236 mrb_define_method(mrb, a, "to_h", mrb_ary_to_h, MRB_ARGS_REQ(0)); 237 mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ANY()); 162 238 } 163 239
Note:
See TracChangeset
for help on using the changeset viewer.