[439] | 1 | /**
|
---|
| 2 | ** @file mruby/array.h - Array class
|
---|
[270] | 3 | **
|
---|
| 4 | ** See Copyright Notice in mruby.h
|
---|
| 5 | */
|
---|
| 6 |
|
---|
| 7 | #ifndef MRUBY_ARRAY_H
|
---|
| 8 | #define MRUBY_ARRAY_H
|
---|
| 9 |
|
---|
[331] | 10 | #include "common.h"
|
---|
[270] | 11 |
|
---|
| 12 | /*
|
---|
| 13 | * Array class
|
---|
| 14 | */
|
---|
| 15 | MRB_BEGIN_DECL
|
---|
| 16 |
|
---|
| 17 |
|
---|
| 18 | typedef struct mrb_shared_array {
|
---|
| 19 | int refcnt;
|
---|
[439] | 20 | mrb_ssize len;
|
---|
[270] | 21 | mrb_value *ptr;
|
---|
| 22 | } mrb_shared_array;
|
---|
| 23 |
|
---|
[439] | 24 | #define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
|
---|
[270] | 25 | struct RArray {
|
---|
| 26 | MRB_OBJECT_HEADER;
|
---|
| 27 | union {
|
---|
[439] | 28 | struct {
|
---|
| 29 | mrb_ssize len;
|
---|
| 30 | union {
|
---|
| 31 | mrb_ssize capa;
|
---|
| 32 | mrb_shared_array *shared;
|
---|
| 33 | } aux;
|
---|
| 34 | mrb_value *ptr;
|
---|
| 35 | } heap;
|
---|
| 36 | void *ary[3];
|
---|
| 37 | } as;
|
---|
[270] | 38 | };
|
---|
| 39 |
|
---|
| 40 | #define mrb_ary_ptr(v) ((struct RArray*)(mrb_ptr(v)))
|
---|
| 41 | #define mrb_ary_value(p) mrb_obj_value((void*)(p))
|
---|
| 42 | #define RARRAY(v) ((struct RArray*)(mrb_ptr(v)))
|
---|
| 43 |
|
---|
[439] | 44 | #define MRB_ARY_EMBED_MASK 7
|
---|
| 45 | #define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
|
---|
| 46 | #define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
|
---|
| 47 | #define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
|
---|
| 48 | #define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
|
---|
| 49 | #define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary))
|
---|
| 50 |
|
---|
| 51 | #define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
|
---|
| 52 | #define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
|
---|
| 53 | #define RARRAY_LEN(a) ARY_LEN(RARRAY(a))
|
---|
| 54 | #define RARRAY_PTR(a) ARY_PTR(RARRAY(a))
|
---|
| 55 | #define ARY_SET_LEN(a,n) do {\
|
---|
| 56 | if (ARY_EMBED_P(a)) {\
|
---|
| 57 | mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \
|
---|
| 58 | ARY_SET_EMBED_LEN(a,n);\
|
---|
| 59 | }\
|
---|
| 60 | else\
|
---|
| 61 | (a)->as.heap.len = (n);\
|
---|
| 62 | } while (0)
|
---|
| 63 | #define ARY_CAPA(a) (ARY_EMBED_P(a)?MRB_ARY_EMBED_LEN_MAX:(a)->as.heap.aux.capa)
|
---|
[270] | 64 | #define MRB_ARY_SHARED 256
|
---|
| 65 | #define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED)
|
---|
| 66 | #define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED)
|
---|
| 67 | #define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED)
|
---|
| 68 |
|
---|
| 69 | void mrb_ary_decref(mrb_state*, mrb_shared_array*);
|
---|
| 70 | MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
|
---|
| 71 | MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int);
|
---|
| 72 |
|
---|
| 73 | /*
|
---|
| 74 | * Initializes a new array.
|
---|
| 75 | *
|
---|
| 76 | * Equivalent to:
|
---|
| 77 | *
|
---|
| 78 | * Array.new
|
---|
| 79 | *
|
---|
| 80 | * @param mrb The mruby state reference.
|
---|
[331] | 81 | * @return The initialized array.
|
---|
[270] | 82 | */
|
---|
| 83 | MRB_API mrb_value mrb_ary_new(mrb_state *mrb);
|
---|
| 84 |
|
---|
[331] | 85 | /*
|
---|
| 86 | * Initializes a new array with initial values
|
---|
| 87 | *
|
---|
| 88 | * Equivalent to:
|
---|
| 89 | *
|
---|
| 90 | * Array[value1, value2, ...]
|
---|
| 91 | *
|
---|
| 92 | * @param mrb The mruby state reference.
|
---|
| 93 | * @param size The numer of values.
|
---|
| 94 | * @param vals The actual values.
|
---|
| 95 | * @return The initialized array.
|
---|
| 96 | */
|
---|
[270] | 97 | MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals);
|
---|
[331] | 98 |
|
---|
| 99 | /*
|
---|
| 100 | * Initializes a new array with two initial values
|
---|
| 101 | *
|
---|
| 102 | * Equivalent to:
|
---|
| 103 | *
|
---|
| 104 | * Array[car, cdr]
|
---|
| 105 | *
|
---|
| 106 | * @param mrb The mruby state reference.
|
---|
| 107 | * @param car The first value.
|
---|
| 108 | * @param cdr The second value.
|
---|
| 109 | * @return The initialized array.
|
---|
| 110 | */
|
---|
[270] | 111 | MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
|
---|
| 112 |
|
---|
| 113 | /*
|
---|
[331] | 114 | * Concatenate two arrays. The target array will be modified
|
---|
| 115 | *
|
---|
| 116 | * Equivalent to:
|
---|
| 117 | * ary.concat(other)
|
---|
| 118 | *
|
---|
| 119 | * @param mrb The mruby state reference.
|
---|
| 120 | * @param self The target array.
|
---|
| 121 | * @param other The array that will be concatenated to self.
|
---|
| 122 | */
|
---|
| 123 | MRB_API void mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other);
|
---|
| 124 |
|
---|
| 125 | /*
|
---|
| 126 | * Create an array from the input. It tries calling to_a on the
|
---|
| 127 | * value. If value does not respond to that, it creates a new
|
---|
| 128 | * array with just this value.
|
---|
| 129 | *
|
---|
| 130 | * @param mrb The mruby state reference.
|
---|
| 131 | * @param value The value to change into an array.
|
---|
| 132 | * @return An array representation of value.
|
---|
| 133 | */
|
---|
| 134 | MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value value);
|
---|
| 135 |
|
---|
| 136 | /*
|
---|
[270] | 137 | * Pushes value into array.
|
---|
| 138 | *
|
---|
| 139 | * Equivalent to:
|
---|
| 140 | *
|
---|
| 141 | * ary << value
|
---|
| 142 | *
|
---|
| 143 | * @param mrb The mruby state reference.
|
---|
| 144 | * @param ary The array in which the value will be pushed
|
---|
| 145 | * @param value The value to be pushed into array
|
---|
| 146 | */
|
---|
| 147 | MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value array, mrb_value value);
|
---|
| 148 |
|
---|
| 149 | /*
|
---|
| 150 | * Pops the last element from the array.
|
---|
| 151 | *
|
---|
| 152 | * Equivalent to:
|
---|
| 153 | *
|
---|
| 154 | * ary.pop
|
---|
| 155 | *
|
---|
| 156 | * @param mrb The mruby state reference.
|
---|
[331] | 157 | * @param ary The array from which the value will be popped.
|
---|
| 158 | * @return The popped value.
|
---|
[270] | 159 | */
|
---|
| 160 | MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
|
---|
| 161 |
|
---|
| 162 | /*
|
---|
| 163 | * Returns a reference to an element of the array on the given index.
|
---|
| 164 | *
|
---|
| 165 | * Equivalent to:
|
---|
| 166 | *
|
---|
| 167 | * ary[n]
|
---|
| 168 | *
|
---|
| 169 | * @param mrb The mruby state reference.
|
---|
| 170 | * @param ary The target array.
|
---|
| 171 | * @param n The array index being referenced
|
---|
| 172 | * @return The referenced value.
|
---|
| 173 | */
|
---|
| 174 | MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
|
---|
| 175 |
|
---|
| 176 | /*
|
---|
| 177 | * Sets a value on an array at the given index
|
---|
| 178 | *
|
---|
| 179 | * Equivalent to:
|
---|
| 180 | *
|
---|
| 181 | * ary[n] = val
|
---|
| 182 | *
|
---|
| 183 | * @param mrb The mruby state reference.
|
---|
| 184 | * @param ary The target array.
|
---|
| 185 | * @param n The array index being referenced.
|
---|
| 186 | * @param val The value being setted.
|
---|
| 187 | */
|
---|
| 188 | MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
|
---|
| 189 |
|
---|
[331] | 190 | /*
|
---|
| 191 | * Replace the array with another array
|
---|
| 192 | *
|
---|
| 193 | * Equivalent to:
|
---|
| 194 | *
|
---|
| 195 | * ary.replace(other)
|
---|
| 196 | *
|
---|
| 197 | * @param mrb The mruby state reference
|
---|
| 198 | * @param self The target array.
|
---|
| 199 | * @param other The array to replace it with.
|
---|
| 200 | */
|
---|
| 201 | MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other);
|
---|
[439] | 202 | MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self);
|
---|
[270] | 203 | MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
|
---|
[331] | 204 |
|
---|
| 205 | /*
|
---|
[439] | 206 | * Unshift an element into the array
|
---|
[331] | 207 | *
|
---|
| 208 | * Equivalent to:
|
---|
| 209 | *
|
---|
| 210 | * ary.unshift(item)
|
---|
| 211 | *
|
---|
| 212 | * @param mrb The mruby state reference.
|
---|
| 213 | * @param self The target array.
|
---|
| 214 | * @param item The item to unshift.
|
---|
| 215 | */
|
---|
[270] | 216 | MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
|
---|
[439] | 217 |
|
---|
| 218 | /*
|
---|
| 219 | * Get nth element in the array
|
---|
| 220 | *
|
---|
| 221 | * Equivalent to:
|
---|
| 222 | *
|
---|
| 223 | * ary[offset]
|
---|
| 224 | *
|
---|
| 225 | * @param ary The target array.
|
---|
| 226 | * @param offset The element position (negative counts from the tail).
|
---|
| 227 | */
|
---|
[270] | 228 | MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
|
---|
[331] | 229 |
|
---|
| 230 | /*
|
---|
[439] | 231 | * Replace subsequence of an array.
|
---|
| 232 | *
|
---|
| 233 | * Equivalent to:
|
---|
| 234 | *
|
---|
| 235 | * ary.shift
|
---|
| 236 | *
|
---|
| 237 | * @param mrb The mruby state reference.
|
---|
| 238 | * @param self The array from which the value will be shifted.
|
---|
| 239 | * @param head Beginning position of a replacement subsequence.
|
---|
| 240 | * @param len Length of a replacement subsequence.
|
---|
| 241 | * @param rpl The array of replacement elements.
|
---|
| 242 | * @return The receiver array.
|
---|
| 243 | */
|
---|
| 244 | MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl);
|
---|
| 245 |
|
---|
| 246 | /*
|
---|
[331] | 247 | * Shifts the first element from the array.
|
---|
| 248 | *
|
---|
| 249 | * Equivalent to:
|
---|
| 250 | *
|
---|
| 251 | * ary.shift
|
---|
| 252 | *
|
---|
| 253 | * @param mrb The mruby state reference.
|
---|
| 254 | * @param self The array from which the value will be shifted.
|
---|
| 255 | * @return The shifted value.
|
---|
| 256 | */
|
---|
[270] | 257 | MRB_API mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
|
---|
[331] | 258 |
|
---|
| 259 | /*
|
---|
[439] | 260 | * Removes all elements from the array
|
---|
[331] | 261 | *
|
---|
| 262 | * Equivalent to:
|
---|
| 263 | *
|
---|
| 264 | * ary.clear
|
---|
| 265 | *
|
---|
| 266 | * @param mrb The mruby state reference.
|
---|
| 267 | * @param self The target array.
|
---|
| 268 | * @return self
|
---|
| 269 | */
|
---|
[270] | 270 | MRB_API mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self);
|
---|
[331] | 271 |
|
---|
| 272 | /*
|
---|
| 273 | * Join the array elements together in a string
|
---|
| 274 | *
|
---|
| 275 | * Equivalent to:
|
---|
| 276 | *
|
---|
| 277 | * ary.join(sep="")
|
---|
| 278 | *
|
---|
| 279 | * @param mrb The mruby state reference.
|
---|
| 280 | * @param ary The target array
|
---|
| 281 | * @param sep The separater, can be NULL
|
---|
| 282 | */
|
---|
[270] | 283 | MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
|
---|
| 284 |
|
---|
[331] | 285 | /*
|
---|
| 286 | * Update the capacity of the array
|
---|
| 287 | *
|
---|
| 288 | * @param mrb The mruby state reference.
|
---|
| 289 | * @param ary The target array.
|
---|
| 290 | * @param new_len The new capacity of the array
|
---|
| 291 | */
|
---|
| 292 | MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
|
---|
| 293 |
|
---|
[270] | 294 | MRB_END_DECL
|
---|
| 295 |
|
---|
| 296 | #endif /* MRUBY_ARRAY_H */
|
---|