carray 3.0.4 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +438 -0
  3. data/README.md +1 -1
  4. data/carray.gemspec +3 -2
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_dispatch.c +19 -20
  7. data/ext/ca_axis_group.c +1 -1
  8. data/ext/ca_categorical_iterator.c +34 -27
  9. data/ext/ca_compare.c +4 -4
  10. data/ext/ca_composite_dispatch.c +9 -9
  11. data/ext/ca_kernel_iterator.c +122 -237
  12. data/ext/ca_kernel_iterator.h +522 -337
  13. data/ext/ca_obj_array.c +69 -19
  14. data/ext/ca_obj_bincmp.c +10 -1
  15. data/ext/ca_obj_binop.c +11 -1
  16. data/ext/ca_obj_bitarray.c +5 -1
  17. data/ext/ca_obj_bitfield.c +60 -43
  18. data/ext/ca_obj_byte_swap.c +4 -1
  19. data/ext/ca_obj_const_string.c +15 -3
  20. data/ext/ca_obj_face.c +44 -1
  21. data/ext/ca_obj_fake.c +3 -1
  22. data/ext/ca_obj_field.c +13 -3
  23. data/ext/ca_obj_grid.c +219 -17
  24. data/ext/ca_obj_meld.c +69 -113
  25. data/ext/ca_obj_moncmp.c +9 -1
  26. data/ext/ca_obj_monop.c +86 -12
  27. data/ext/ca_obj_object.c +118 -32
  28. data/ext/ca_obj_record.c +3 -0
  29. data/ext/ca_obj_reduce.c +19 -1
  30. data/ext/ca_obj_refer.c +80 -26
  31. data/ext/ca_obj_remap.c +69 -10
  32. data/ext/ca_obj_roll.c +27 -6
  33. data/ext/ca_obj_select.c +38 -6
  34. data/ext/ca_obj_select_axis.c +1 -0
  35. data/ext/ca_obj_shift.c +32 -7
  36. data/ext/ca_obj_stack.c +311 -111
  37. data/ext/ca_obj_stride.c +159 -64
  38. data/ext/ca_obj_string.c +27 -2
  39. data/ext/ca_obj_tile.c +28 -7
  40. data/ext/ca_obj_transpose.c +8 -4
  41. data/ext/ca_obj_triop.c +12 -1
  42. data/ext/ca_obj_window.c +80 -50
  43. data/ext/ca_op_ipower.c +12 -12
  44. data/ext/ca_sort_kernels.h +6 -3
  45. data/ext/caframe_csv_reader.c +1 -1
  46. data/ext/carray.h +35 -1
  47. data/ext/carray_access.c +43 -67
  48. data/ext/carray_address_basis.c +134 -0
  49. data/ext/carray_attribute.c +32 -0
  50. data/ext/carray_broadcast.c +3 -4
  51. data/ext/carray_build_flags.h +1 -1
  52. data/ext/carray_cast.c +251 -93
  53. data/ext/carray_cast_func.rb +56 -26
  54. data/ext/carray_conversion.c +11 -7
  55. data/ext/carray_core.c +814 -72
  56. data/ext/carray_count.c +6 -0
  57. data/ext/carray_element.c +22 -13
  58. data/ext/carray_factorize.c +20 -20
  59. data/ext/carray_generate.c +8 -2
  60. data/ext/carray_histogram.c +26 -4
  61. data/ext/carray_index_classifier.c +4 -4
  62. data/ext/carray_internal.h +159 -12
  63. data/ext/carray_kernels_bincmp.c +2174 -170
  64. data/ext/carray_kernels_binop.c +25653 -5487
  65. data/ext/carray_kernels_init.c +8 -8
  66. data/ext/carray_kernels_moncmp.c +96 -96
  67. data/ext/carray_kernels_monop.c +12253 -5235
  68. data/ext/carray_kernels_reduce_aggregate.c +6150 -2423
  69. data/ext/carray_kernels_reduce_boolean.c +1533 -15
  70. data/ext/carray_kernels_reduce_cumulative.c +2442 -882
  71. data/ext/carray_kernels_reduce_extreme.c +5658 -1661
  72. data/ext/carray_kernels_reduce_variance.c +2534 -402
  73. data/ext/carray_kernels_scan.c +368 -368
  74. data/ext/carray_kernels_search.c +4551 -604
  75. data/ext/carray_kernels_sort.c +659 -751
  76. data/ext/carray_kernels_triop.c +114 -114
  77. data/ext/carray_key_windows.c +4 -0
  78. data/ext/carray_lazy.c +47 -0
  79. data/ext/carray_loop.c +1 -1
  80. data/ext/carray_mask.c +175 -161
  81. data/ext/carray_median_percentile.c +4 -4
  82. data/ext/carray_memory_view.c +15 -9
  83. data/ext/carray_operator.c +152 -49
  84. data/ext/carray_order.c +230 -10
  85. data/ext/carray_random.c +22 -19
  86. data/ext/carray_scatter.c +24 -7
  87. data/ext/carray_slab.c +128 -29
  88. data/ext/carray_sort.c +224 -16
  89. data/ext/carray_sort_kernel.c +5 -7
  90. data/ext/carray_struct.c +35 -43
  91. data/ext/carray_test.c +74 -19
  92. data/ext/carray_time_text.c +6 -4
  93. data/ext/carray_utils.c +63 -21
  94. data/ext/extconf.rb +11 -0
  95. data/ext/mkkernel.rb +546 -199
  96. data/ext/ruby_carray.c +4 -1
  97. data/ext/version.h +4 -4
  98. data/lib/carray/attribute.rb +42 -5
  99. data/lib/carray/autoload_carray.rb +3 -3
  100. data/lib/carray/autoload_method_extension.rb +5 -3
  101. data/lib/carray/axis_group.rb +13 -7
  102. data/lib/carray/basics.rb +28 -8
  103. data/lib/carray/block_iterator.rb +17 -3
  104. data/lib/carray/categorical.rb +35 -23
  105. data/lib/carray/categorical_iterator.rb +8 -8
  106. data/lib/carray/complex.rb +2 -2
  107. data/lib/carray/conditional.rb +3 -2
  108. data/lib/carray/const_string.rb +10 -0
  109. data/lib/carray/data_type_extension.rb +8 -1
  110. data/lib/carray/fixlen_string.rb +41 -2
  111. data/lib/carray/frame/column_verbs.rb +48 -16
  112. data/lib/carray/frame/concat.rb +17 -3
  113. data/lib/carray/frame/convert.rb +19 -0
  114. data/lib/carray/frame/csv_parser.rb +32 -32
  115. data/lib/carray/frame/describe.rb +4 -2
  116. data/lib/carray/frame/frame.rb +405 -85
  117. data/lib/carray/frame/group.rb +777 -64
  118. data/lib/carray/frame/io.rb +212 -72
  119. data/lib/carray/frame/join.rb +146 -37
  120. data/lib/carray/frame/records.rb +3 -3
  121. data/lib/carray/frame/reshape.rb +89 -11
  122. data/lib/carray/frame/sort.rb +57 -9
  123. data/lib/carray/frame/verbs.rb +384 -49
  124. data/lib/carray/frame/windows.rb +44 -6
  125. data/lib/carray/fuse_source.rb +31 -2
  126. data/lib/carray/inspect.rb +7 -2
  127. data/lib/carray/iterator.rb +32 -0
  128. data/lib/carray/lazy.rb +52 -8
  129. data/lib/carray/mask_gap_fill.rb +37 -17
  130. data/lib/carray/meld_reduce.rb +1 -1
  131. data/lib/carray/methods/choose.rb +3 -2
  132. data/lib/carray/methods/is_in.rb +8 -1
  133. data/lib/carray/methods/meshgrid.rb +3 -1
  134. data/lib/carray/runtime.rb +47 -8
  135. data/lib/carray/segment_iterator.rb +35 -16
  136. data/lib/carray/serialize.rb +53 -19
  137. data/lib/carray/stack.rb +33 -18
  138. data/lib/carray/string.rb +8 -0
  139. data/lib/carray/string_operation_extension.rb +13 -5
  140. data/lib/carray/struct_builder.rb +5 -3
  141. data/lib/carray/time.rb +112 -68
  142. data/lib/carray/window_iterator.rb +16 -4
  143. data/yard-stubs/ca_obj_array.rb +26 -1
  144. data/yard-stubs/ca_obj_transpose.rb +5 -4
  145. data/yard-stubs/carray_attribute.rb +3 -1
  146. data/yard-stubs/carray_cast.rb +10 -5
  147. data/yard-stubs/carray_conversion.rb +13 -3
  148. data/yard-stubs/carray_element.rb +7 -6
  149. data/yard-stubs/carray_mask.rb +28 -4
  150. data/yard-stubs/carray_math.rb +45 -20
  151. data/yard-stubs/carray_memory_view.rb +7 -0
  152. data/yard-stubs/carray_order.rb +100 -4
  153. data/yard-stubs/carray_scatter.rb +7 -5
  154. data/yard-stubs/carray_test.rb +7 -4
  155. metadata +18 -4
data/ext/ca_obj_remap.c CHANGED
@@ -304,8 +304,9 @@ ca_remap_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
304
304
 
305
305
  paddrs = ALLOCV_N(ca_size_t, holder, n);
306
306
  ca_xfer_addrs(ca->idx, n, addrs, paddrs, CA_XFER_GET);
307
- /* idx is read live, so its values are checked here, not at
308
- construction: negative counts from the end, out of range raises
307
+ /* idx is read-only once the view holds it, but its values are still
308
+ checked on every transfer (the private without_read_only_flag can
309
+ lift the flag): negative counts from the end, out of range raises
309
310
  before the parent is touched. */
310
311
  for ( i = 0; i < n; i++ ) {
311
312
  CA_CHECK_INDEX(paddrs[i], ca->parent->elements);
@@ -366,9 +367,19 @@ ca_remap_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
366
367
  ALLOCV_END(holder);
367
368
  }
368
369
 
369
- /* xfer_all: whole-view delivery. Sequential view-flat addresses
370
- [0..elements) routed through xfer_addrs -- one ALLOCV for the addr
371
- list, then two batched ca_xfer_addrs calls inside xfer_addrs.
370
+ /* xfer_all: whole-view delivery. The whole view reads every cell of idx
371
+ in order, so when idx holds its cells in memory those cells are the
372
+ parent addresses: they are checked in one pass, a negative one counting
373
+ from the end of the parent.
374
+
375
+ idx itself is handed to the parent only when the parent holds its cells
376
+ in memory and shares no root with idx: that transfer is a plain copy, so
377
+ no Ruby runs while the parent reads the list and a scatter cannot
378
+ rewrite it. Any other parent (a view, a CAObject whose hooks run Ruby)
379
+ gets a copy of the addresses taken in the checking pass, so nothing it
380
+ does can change an address after it was checked, or change idx.
381
+ Without idx in memory, the sequential view-flat addresses [0..elements)
382
+ go through xfer_addrs.
372
383
 
373
384
  No ca_attach(parent) / ca_attach(idx). */
374
385
  static void
@@ -382,6 +393,46 @@ ca_remap_func_xfer_all (void *ap, void *data, int dir)
382
393
 
383
394
  if ( n == 0 ) return;
384
395
 
396
+ if ( ca->idx->ptr ) {
397
+ ca_size_t *iaddrs = (ca_size_t *) ca->idx->ptr;
398
+ ca_size_t pn = ca->parent->elements;
399
+ ca_size_t *paddrs;
400
+
401
+ if ( ca->parent->ptr && ! ca_shares_root(ca->parent, ca->idx) ) {
402
+ int lendable = 1;
403
+ for ( i = 0; i < n; i++ ) {
404
+ ca_size_t a = iaddrs[i];
405
+ if ( a < 0 ) {
406
+ lendable = 0;
407
+ a += pn;
408
+ }
409
+ if ( a < 0 || a >= pn ) {
410
+ ca_index_out_of_range(iaddrs[i], pn, "index");
411
+ }
412
+ }
413
+ if ( lendable ) {
414
+ ca_xfer_addrs(ca->parent, n, iaddrs, data, dir);
415
+ return;
416
+ }
417
+ }
418
+
419
+ paddrs = ALLOCV_N(ca_size_t, holder, n);
420
+ for ( i = 0; i < n; i++ ) {
421
+ ca_size_t a = iaddrs[i];
422
+ if ( a < 0 ) {
423
+ a += pn;
424
+ }
425
+ if ( a < 0 || a >= pn ) {
426
+ ALLOCV_END(holder);
427
+ ca_index_out_of_range(iaddrs[i], pn, "index");
428
+ }
429
+ paddrs[i] = a;
430
+ }
431
+ ca_xfer_addrs(ca->parent, n, paddrs, data, dir);
432
+ ALLOCV_END(holder);
433
+ return;
434
+ }
435
+
385
436
  vaddrs = ALLOCV_N(ca_size_t, holder, n);
386
437
  for ( i = 0; i < n; i++ ) vaddrs[i] = i;
387
438
  ca_remap_func_xfer_addrs(ca, n, vaddrs, data, dir);
@@ -417,7 +468,13 @@ ca_operation_function_t ca_remap_func = {
417
468
  carray_partition.c). Callers are expected to have already checked the
418
469
  routing preconditions (same shape, idx data_type == CA_SIZE);
419
470
  ca_remap_setup raises ArgumentError on mismatch as a defensive
420
- fallback. */
471
+ fallback.
472
+
473
+ The view takes rmapper over: every caller hands a fresh array no one
474
+ else holds, and it is marked read-only here, so the mapping a view was
475
+ made with cannot be rewritten through #mapper. CAGrid and CASelect
476
+ keep their indices where Ruby cannot reach them; this is the same
477
+ promise for an index array that stays visible. */
421
478
  VALUE
422
479
  rb_ca_remap_new (VALUE cary, VALUE rmapper)
423
480
  {
@@ -437,13 +494,14 @@ rb_ca_remap_new (VALUE cary, VALUE rmapper)
437
494
  covers the view's. ca->idx is a raw pointer into idx's struct;
438
495
  keeping rmapper reachable through the view keeps it alive. */
439
496
  rb_ivar_set(obj, rb_intern("remap_idx"), rmapper);
497
+ rb_ca_set_read_only_flag(rmapper);
440
498
  return obj;
441
499
  }
442
500
 
443
- /* Read-only accessor for the per-cell index CArray that defines this
444
- CARemap's mapping: the array the view reads. For ca[mapper] it is a
445
- copy of mapper taken at the call, so a later change to mapper does
446
- not reach the view. Companion to
501
+ /* Accessor for the per-cell index CArray that defines this CARemap's
502
+ mapping: the array the view reads, itself read-only. For ca[mapper]
503
+ it is a copy of mapper taken at the call, so a later change to mapper
504
+ does not reach the view. Companion to
447
505
  CABlock#start / CAStride#strides / CAWindow#count etc. — the view
448
506
  hierarchy is preserved so each named view class exposes its own
449
507
  defining semantic state. */
@@ -526,6 +584,7 @@ Init_ca_obj_remap (void)
526
584
  rb_cCARemapMask,
527
585
  &caremap_mask_data_type,
528
586
  &ca_remap_func, sizeof(ca_remap_func));
587
+ ca_register_cell_moving_view(CA_OBJ_REMAP);
529
588
 
530
589
  /* Defining semantic state accessor — companion to CABlock#start /
531
590
  CAStride#strides / CAWindow#count. The hierarchy-preserving
data/ext/ca_obj_roll.c CHANGED
@@ -112,6 +112,8 @@ ca_roll_setup (CARoll *ca, CArray *parent, ca_size_t *shift)
112
112
  ca->parent = parent;
113
113
  ca->attach = 0;
114
114
  ca->nosync = 0;
115
+ ca->reps = NULL; /* set before either allocation can raise */
116
+ ca->dim = NULL;
115
117
  ca->reps = ALLOC_N(ca_size_t, ndim); /* repurposed as shift[] */
116
118
  ca->dim = ALLOC_N(ca_size_t, ndim);
117
119
 
@@ -130,15 +132,33 @@ ca_roll_setup (CARoll *ca, CArray *parent, ca_size_t *shift)
130
132
  return 0;
131
133
  }
132
134
 
135
+ typedef struct {
136
+ CARoll *ca;
137
+ CArray *parent;
138
+ ca_size_t *shift;
139
+ } ca_roll_new_arg;
140
+
141
+ static VALUE
142
+ ca_roll_new_setup (VALUE varg)
143
+ {
144
+ ca_roll_new_arg *a = (ca_roll_new_arg *) varg;
145
+ ca_roll_setup(a->ca, a->parent, a->shift);
146
+ return Qnil;
147
+ }
148
+
149
+ /* The setup allocates reps and dim after the struct: when either fails,
150
+ the struct goes too. */
133
151
  CARoll *
134
152
  ca_roll_new (CArray *parent, ca_size_t *shift)
135
153
  {
136
- CARoll *ca;
154
+ ca_roll_new_arg a;
137
155
  ca_roll_setup(NULL, parent, shift);
138
- ca = ALLOC(CARoll);
139
- ca_roll_setup(ca, parent, shift);
140
- ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
141
- return ca;
156
+ a.ca = ALLOC(CARoll);
157
+ a.parent = parent;
158
+ a.shift = shift;
159
+ ca_fill_or_free((CArray *) a.ca, ca_roll_new_setup, (VALUE) &a);
160
+ ca_fill_or_free((CArray *) a.ca, ca_view_inherit_mask, (VALUE) a.ca);
161
+ return a.ca;
142
162
  }
143
163
 
144
164
  static void
@@ -629,7 +649,7 @@ rb_ca_roll (int argc, VALUE *argv, VALUE self)
629
649
  }
630
650
  for ( i = 0; i < ca->ndim; i++ ) {
631
651
  if ( i < argc ) {
632
- shift[i] = NUM2SIZE(argv[i]);
652
+ shift[i] = ca_integer_arg(argv[i], "a shift", NULL);
633
653
  } else {
634
654
  shift[i] = 0;
635
655
  }
@@ -713,6 +733,7 @@ Init_ca_obj_roll (void)
713
733
  &caroll_data_type,
714
734
  rb_cCARollMask,
715
735
  &caroll_mask_data_type, &ca_roll_func, sizeof(ca_roll_func));
736
+ ca_register_cell_moving_view(CA_OBJ_ROLL);
716
737
  rb_define_const(rb_cObject, "CA_OBJ_ROLL", INT2NUM(CA_OBJ_ROLL));
717
738
 
718
739
  rb_define_method(rb_cCArray, "roll", rb_ca_roll, -1);
data/ext/ca_obj_select.c CHANGED
@@ -130,7 +130,8 @@ ca_select_snapshot (CArray *select)
130
130
 
131
131
  /* Set up the view over `parent` from an owned selector snapshot (see
132
132
  ca_select_snapshot) and pre-compute ca->indices (TRUE positions in flat
133
- parent order). Does not raise. */
133
+ parent order). Raises only when the indices cannot be allocated, after
134
+ every field free_ca_select reads is set. */
134
135
  static int
135
136
  ca_select_setup (CASelect *ca, CArray *parent, CArray *snapshot)
136
137
  {
@@ -204,21 +205,51 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *snapshot)
204
205
  ca->dim = &(ca->_dim);
205
206
  ca->dim[0] = ca->elements;
206
207
 
207
- if ( ca_is_scalar(snapshot) ) {
208
+ /* A selection of a scalar is one only while it picks the cell: a scalar
209
+ is one cell along one axis. */
210
+ if ( ca_is_scalar(snapshot) && ca->elements == 1 ) {
208
211
  ca_set_flag(ca, CA_FLAG_SCALAR);
209
212
  }
210
213
 
211
214
  return 0;
212
215
  }
213
216
 
217
+ typedef struct {
218
+ CASelect *ca;
219
+ CArray *parent;
220
+ CArray *snapshot;
221
+ } ca_select_new_arg;
222
+
223
+ static VALUE
224
+ ca_select_new_alloc (VALUE varg)
225
+ {
226
+ ca_select_new_arg *a = (ca_select_new_arg *) varg;
227
+ a->ca = ALLOC(CASelect);
228
+ return Qnil;
229
+ }
230
+
231
+ static VALUE
232
+ ca_select_new_setup (VALUE varg)
233
+ {
234
+ ca_select_new_arg *a = (ca_select_new_arg *) varg;
235
+ ca_select_setup(a->ca, a->parent, a->snapshot);
236
+ return Qnil;
237
+ }
238
+
239
+ /* The struct and the indices are allocated after the snapshot. When the
240
+ struct cannot be allocated the snapshot goes; when the indices cannot,
241
+ the struct goes and takes the snapshot with it (the setup stores the
242
+ snapshot before it allocates the indices). */
214
243
  CArray *
215
244
  ca_select_new (CArray *parent, CArray *select)
216
245
  {
217
- CArray *snapshot = ca_select_snapshot(select);
246
+ ca_select_new_arg a;
247
+ a.parent = parent;
248
+ a.snapshot = ca_select_snapshot(select);
218
249
  /* check: the setup checks nothing */
219
- CASelect *ca = ALLOC(CASelect);
220
- ca_select_setup(ca, parent, snapshot);
221
- return (CArray*) ca;
250
+ ca_fill_or_free(a.snapshot, ca_select_new_alloc, (VALUE) &a);
251
+ ca_fill_or_free((CArray *) a.ca, ca_select_new_setup, (VALUE) &a);
252
+ return (CArray*) a.ca;
222
253
  }
223
254
 
224
255
  /* Alias for source compatibility. Both constructors produce a
@@ -639,6 +670,7 @@ rb_cm_initialize_copy (VALUE self, VALUE other)
639
670
  void
640
671
  Init_ca_obj_select (void)
641
672
  {
673
+ ca_register_cell_moving_view(CA_OBJ_SELECT);
642
674
  /* rb_cCASelect and CA_OBJ_SELECT are defined in ruby_carray.c;
643
675
  this file only registers the constant + allocator. */
644
676
  rb_define_const(rb_cObject, "CA_OBJ_SELECT", INT2NUM(CA_OBJ_SELECT));
@@ -1238,6 +1238,7 @@ Init_ca_obj_select_axis (void)
1238
1238
  rb_cCASelectAxisMask,
1239
1239
  &caselectaxis_mask_data_type,
1240
1240
  &ca_select_axis_func, sizeof(ca_select_axis_func));
1241
+ ca_register_cell_moving_view(CA_OBJ_SELECT_AXIS);
1241
1242
  rb_define_const(rb_cObject, "CA_OBJ_SELECT_AXIS", INT2NUM(CA_OBJ_SELECT_AXIS));
1242
1243
 
1243
1244
  rb_define_alloc_func(rb_cCASelectAxis, rb_ca_select_axis_s_allocate);
data/ext/ca_obj_shift.c CHANGED
@@ -120,16 +120,40 @@ ca_shift_setup (CAShift *ca, CArray *parent,
120
120
  return 0;
121
121
  }
122
122
 
123
+ typedef struct {
124
+ CAShift *ca;
125
+ CArray *parent;
126
+ ca_size_t *shift;
127
+ char *fill;
128
+ int8_t *roll;
129
+ int fill_mask;
130
+ } ca_shift_new_arg;
131
+
132
+ static VALUE
133
+ ca_shift_new_setup (VALUE varg)
134
+ {
135
+ ca_shift_new_arg *a = (ca_shift_new_arg *) varg;
136
+ ca_shift_setup(a->ca, a->parent, a->shift, a->fill, a->roll, a->fill_mask);
137
+ return Qnil;
138
+ }
139
+
140
+ /* The setup allocates the fill value after the struct and its pool: when
141
+ that fails, the struct goes too. */
123
142
  CAShift *
124
143
  ca_shift_new (CArray *parent, ca_size_t *shift, char *fill, int8_t *roll,
125
144
  int fill_mask)
126
145
  {
127
- CAShift *ca;
146
+ ca_shift_new_arg a;
128
147
  ca_shift_setup(NULL, parent, shift, fill, roll, fill_mask);
129
- ca = (CAShift *) ca_array_alloc(CA_OBJ_SHIFT, parent->ndim);
130
- ca_shift_setup(ca, parent, shift, fill, roll, fill_mask);
131
- ca_fill_or_free((CArray *) ca, ca_window_create_bounds_mask, (VALUE) ca);
132
- return ca;
148
+ a.ca = (CAShift *) ca_array_alloc(CA_OBJ_SHIFT, parent->ndim);
149
+ a.parent = parent;
150
+ a.shift = shift;
151
+ a.fill = fill;
152
+ a.roll = roll;
153
+ a.fill_mask = fill_mask;
154
+ ca_fill_or_free((CArray *) a.ca, ca_shift_new_setup, (VALUE) &a);
155
+ ca_fill_or_free((CArray *) a.ca, ca_window_create_bounds_mask, (VALUE) a.ca);
156
+ return a.ca;
133
157
  }
134
158
 
135
159
  /* Clone: produce a CAShift (not CAWindow) by rebuilding via setup.
@@ -216,7 +240,7 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
216
240
  }
217
241
 
218
242
  for (i=0; i<ca->ndim; i++) {
219
- shift[i] = NUM2SIZE(argv[i]);
243
+ shift[i] = ca_integer_arg(argv[i], "a shift", NULL);
220
244
  }
221
245
 
222
246
  if ( rb_block_given_p() ) {
@@ -264,7 +288,7 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
264
288
  }
265
289
 
266
290
  for (i=0; i<ca->ndim; i++) {
267
- roll[i] = NUM2INT(rb_ary_entry(rroll, i));
291
+ roll[i] = ca_integer_arg(rb_ary_entry(rroll, i), "a shift", NULL);
268
292
  }
269
293
  }
270
294
 
@@ -339,6 +363,7 @@ Init_ca_obj_shift (void)
339
363
  &cashift_data_type,
340
364
  rb_cCAShiftMask,
341
365
  &cashift_mask_data_type, &ca_shift_func, sizeof(ca_shift_func));
366
+ ca_register_cell_moving_view(CA_OBJ_SHIFT);
342
367
  rb_define_const(rb_cObject, "CA_OBJ_SHIFT", INT2NUM(CA_OBJ_SHIFT));
343
368
 
344
369
  rb_define_method(rb_cCArray, "shift", rb_ca_shift, -1);