carray 2.0.0 → 3.0.0
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.
- checksums.yaml +4 -4
- data/.yardopts +5 -25
- data/CHANGELOG.md +16 -0
- data/LICENSE +1 -1
- data/NEWS.md +3 -0
- data/README.md +128 -44
- data/carray.gemspec +22 -24
- data/ext/ca_array_pool.c +91 -0
- data/ext/ca_axis_descriptor.h +186 -0
- data/ext/ca_axis_dispatch.c +924 -0
- data/ext/ca_axis_group.c +1208 -0
- data/ext/ca_bincmp_dispatch.c +76 -0
- data/ext/ca_bincmp_dispatch.h +85 -0
- data/ext/ca_binop_dispatch.c +125 -0
- data/ext/ca_binop_dispatch.h +159 -0
- data/ext/ca_categorical_iterator.c +1375 -0
- data/ext/ca_compare.c +94 -0
- data/ext/ca_compare.h +26 -0
- data/ext/ca_composite_dispatch.c +414 -0
- data/ext/ca_composite_dispatch.h +116 -0
- data/ext/ca_for_buffer.h +96 -0
- data/ext/ca_for_each_element.h +241 -0
- data/ext/ca_group_iter.c +304 -0
- data/ext/ca_iter_substrate.h +325 -0
- data/ext/ca_kernel_iterator.c +4321 -0
- data/ext/ca_kernel_iterator.h +2603 -0
- data/ext/ca_moncmp_dispatch.c +37 -0
- data/ext/ca_moncmp_dispatch.h +62 -0
- data/ext/ca_monop_dispatch.c +200 -0
- data/ext/ca_monop_dispatch.h +235 -0
- data/ext/ca_obj_array.c +355 -359
- data/ext/ca_obj_bincmp.c +809 -0
- data/ext/ca_obj_binop.c +892 -0
- data/ext/ca_obj_bitarray.c +369 -164
- data/ext/ca_obj_bitfield.c +294 -234
- data/ext/ca_obj_block.c +189 -711
- data/ext/ca_obj_byte_swap.c +766 -0
- data/ext/ca_obj_const_string.c +965 -0
- data/ext/ca_obj_face.c +670 -0
- data/ext/ca_obj_face.h +247 -0
- data/ext/ca_obj_fake.c +228 -100
- data/ext/ca_obj_farray.c +54 -441
- data/ext/ca_obj_field.c +82 -529
- data/ext/ca_obj_fixlen_string.c +306 -0
- data/ext/ca_obj_grid.c +858 -440
- data/ext/ca_obj_meld.c +1034 -0
- data/ext/ca_obj_moncmp.c +569 -0
- data/ext/ca_obj_monop.c +1111 -0
- data/ext/ca_obj_object.c +774 -298
- data/ext/ca_obj_record.c +468 -0
- data/ext/ca_obj_reduce.c +97 -82
- data/ext/ca_obj_refer.c +569 -459
- data/ext/ca_obj_remap.c +475 -0
- data/ext/ca_obj_repeat.c +92 -477
- data/ext/ca_obj_roll.c +616 -0
- data/ext/ca_obj_select.c +344 -296
- data/ext/ca_obj_select_axis.c +1296 -0
- data/ext/ca_obj_shift.c +230 -792
- data/ext/ca_obj_source.c +78 -0
- data/ext/ca_obj_stack.c +1173 -0
- data/ext/ca_obj_stride.c +2501 -0
- data/ext/ca_obj_string.c +268 -0
- data/ext/ca_obj_tile.c +614 -0
- data/ext/ca_obj_time.c +546 -0
- data/ext/ca_obj_timedelta.c +435 -0
- data/ext/ca_obj_transpose.c +62 -516
- data/ext/ca_obj_triop.c +746 -0
- data/ext/ca_obj_unbound_repeat.c +208 -241
- data/ext/ca_obj_window.c +1131 -563
- data/ext/ca_op_byte_swap.c +175 -0
- data/ext/ca_op_ipower.c +319 -0
- data/ext/ca_op_powi.h +88 -0
- data/ext/ca_sort_kernels.h +132 -0
- data/ext/ca_sweep_engine.c +430 -0
- data/ext/ca_sweep_engine.h +157 -0
- data/ext/ca_transform_common.c +228 -0
- data/ext/ca_triop_dispatch.c +55 -0
- data/ext/ca_triop_dispatch.h +62 -0
- data/ext/carray.h +795 -402
- data/ext/carray_access.c +831 -711
- data/ext/carray_attribute.c +98 -330
- data/ext/carray_bincount.c +255 -0
- data/ext/carray_broadcast.c +283 -0
- data/ext/carray_call_cfunc.c +1360 -828
- data/ext/carray_call_cfunc.h +160 -0
- data/ext/carray_cast.c +1212 -301
- data/ext/carray_cast_func.rb +81 -40
- data/ext/carray_class.c +53 -63
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +350 -346
- data/ext/carray_copy.c +156 -268
- data/ext/carray_core.c +1342 -199
- data/ext/carray_count.c +312 -0
- data/ext/carray_data_type.c +43 -19
- data/ext/carray_element.c +585 -213
- data/ext/carray_factorize.c +2542 -0
- data/ext/carray_generate.c +230 -559
- data/ext/carray_histogram.c +490 -0
- data/ext/carray_hold.c +228 -0
- data/ext/carray_index_classifier.c +1035 -0
- data/ext/carray_index_classifier.h +27 -0
- data/ext/carray_internal.h +120 -0
- data/ext/carray_kernels_bincmp.c +4445 -0
- data/ext/carray_kernels_binop.c +10979 -0
- data/ext/carray_kernels_init.c +36 -0
- data/ext/carray_kernels_map.c +3466 -0
- data/ext/carray_kernels_moncmp.c +2096 -0
- data/ext/carray_kernels_monop.c +18312 -0
- data/ext/carray_kernels_reduce_aggregate.c +25836 -0
- data/ext/carray_kernels_reduce_boolean.c +329 -0
- data/ext/carray_kernels_reduce_cumulative.c +14592 -0
- data/ext/carray_kernels_reduce_extreme.c +16947 -0
- data/ext/carray_kernels_reduce_variance.c +3909 -0
- data/ext/carray_kernels_scan.c +3692 -0
- data/ext/carray_kernels_search.c +32137 -0
- data/ext/carray_kernels_sort.c +10625 -0
- data/ext/carray_kernels_triop.c +1391 -0
- data/ext/carray_lazy.c +567 -0
- data/ext/carray_loop.c +88 -200
- data/ext/carray_mask.c +848 -154
- data/ext/carray_math_kernel.h +120 -0
- data/ext/carray_mathfunc.c +10 -241
- data/ext/carray_median_percentile.c +1257 -0
- data/ext/carray_memory_view.c +1625 -0
- data/ext/carray_operator.c +1526 -318
- data/ext/carray_order.c +664 -1394
- data/ext/carray_partition.c +416 -0
- data/ext/carray_random.c +518 -0
- data/ext/carray_scatter.c +357 -0
- data/ext/carray_slab.c +1219 -0
- data/ext/carray_slab.h +84 -0
- data/ext/carray_sort.c +829 -0
- data/ext/carray_sort_kernel.c +620 -0
- data/ext/carray_struct.c +695 -0
- data/ext/carray_test.c +343 -229
- data/ext/carray_undef.c +34 -17
- data/ext/carray_utils.c +175 -74
- data/ext/extconf.rb +216 -55
- data/ext/mk_call_cfunc.rb +480 -0
- data/ext/mkkernel.rb +8842 -0
- data/ext/ruby_carray.c +202 -101
- data/ext/version.h +4 -14
- data/ext/version.rb +5 -13
- data/lib/carray/arrow_tensor.rb +401 -0
- data/lib/carray/attribute.rb +166 -0
- data/lib/carray/autoload_carray.rb +220 -0
- data/lib/carray/autoload_method_extension.rb +44 -0
- data/lib/carray/axis_group.rb +711 -0
- data/lib/carray/basics.rb +481 -0
- data/lib/carray/bincount_nd.rb +358 -0
- data/lib/carray/block_iterator.rb +604 -0
- data/lib/carray/boolean_reduce.rb +109 -0
- data/lib/carray/categorical.rb +561 -0
- data/lib/carray/categorical_iterator.rb +1062 -0
- data/lib/carray/complex.rb +150 -0
- data/lib/carray/conditional.rb +216 -0
- data/lib/carray/const_string.rb +228 -0
- data/lib/carray/construct.rb +139 -328
- data/lib/carray/core_extensions.rb +240 -0
- data/lib/carray/data_type_extension.rb +233 -0
- data/lib/carray/fixlen_string.rb +95 -0
- data/lib/carray/frame/concat.rb +132 -0
- data/lib/carray/frame/convert.rb +95 -0
- data/lib/carray/frame/csv_parser.rb +211 -0
- data/lib/carray/frame/frame.rb +649 -0
- data/lib/carray/frame/group.rb +186 -0
- data/lib/carray/frame/io.rb +164 -0
- data/lib/carray/frame/join.rb +248 -0
- data/lib/carray/frame/records.rb +99 -0
- data/lib/carray/frame/sort.rb +113 -0
- data/lib/carray/frame/verbs.rb +299 -0
- data/lib/carray/frame.rb +16 -0
- data/lib/carray/histogram.rb +512 -0
- data/lib/carray/inspect.rb +37 -20
- data/lib/carray/iterator.rb +57 -349
- data/lib/carray/lazy.rb +889 -0
- data/lib/carray/mask_gap_fill.rb +200 -0
- data/lib/carray/math.rb +78 -342
- data/lib/carray/meld_reduce.rb +289 -0
- data/lib/carray/methods/align_addr.rb +116 -0
- data/lib/carray/methods/bin.rb +128 -0
- data/lib/carray/methods/bincount.rb +87 -0
- data/lib/carray/methods/bit_string.rb +92 -0
- data/lib/carray/methods/broadcast.rb +63 -0
- data/lib/carray/methods/choose.rb +39 -0
- data/lib/carray/methods/composition.rb +280 -0
- data/lib/carray/methods/gather_nd.rb +206 -0
- data/lib/carray/methods/index.rb +39 -0
- data/lib/carray/methods/insert_block.rb +99 -0
- data/lib/carray/methods/is_in.rb +141 -0
- data/lib/carray/methods/join.rb +90 -0
- data/lib/carray/methods/locate_addr.rb +47 -0
- data/lib/carray/methods/mask_duplicates.rb +41 -0
- data/lib/carray/methods/meshgrid.rb +91 -0
- data/lib/carray/methods/mode.rb +126 -0
- data/lib/carray/methods/nunique.rb +46 -0
- data/lib/carray/methods/resize.rb +56 -0
- data/lib/carray/methods/snap.rb +156 -0
- data/lib/carray/methods/string_format.rb +57 -0
- data/lib/carray/methods/unique.rb +47 -0
- data/lib/carray/methods/value_counts.rb +71 -0
- data/lib/carray/mkmf.rb +124 -101
- data/lib/carray/runtime.rb +108 -0
- data/lib/carray/serialize.rb +478 -167
- data/lib/carray/slab_iterator.rb +292 -0
- data/lib/carray/stack.rb +291 -0
- data/lib/carray/string.rb +56 -180
- data/lib/carray/string_operation_extension.rb +289 -0
- data/lib/carray/struct.rb +335 -323
- data/lib/carray/struct_builder.rb +697 -0
- data/lib/carray/table.rb +41 -2
- data/lib/carray/time.rb +2255 -38
- data/lib/carray/window_iterator.rb +655 -0
- data/lib/carray.rb +55 -57
- metadata +163 -130
- data/Rakefile +0 -51
- data/TODO.md +0 -18
- data/ext/ca_iter_block.c +0 -257
- data/ext/ca_iter_dimension.c +0 -299
- data/ext/ca_iter_window.c +0 -214
- data/ext/ca_obj_mapping.c +0 -644
- data/ext/carray_iterator.c +0 -641
- data/ext/carray_math.rb +0 -850
- data/ext/carray_numeric.c +0 -259
- data/ext/carray_sort_addr.c +0 -254
- data/ext/carray_stat.c +0 -2100
- data/ext/carray_stat_proc.rb +0 -1999
- data/ext/mkmath.rb +0 -741
- data/ext/ruby_ccomplex.c +0 -509
- data/ext/ruby_float_func.c +0 -86
- data/lib/carray/array.rb +0 -8
- data/lib/carray/autoload/autoload_base.rb +0 -19
- data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
- data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
- data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
- data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
- data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
- data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
- data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
- data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
- data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
- data/lib/carray/autoload/autoload_gem_random.rb +0 -8
- data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
- data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
- data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
- data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
- data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
- data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
- data/lib/carray/autoload/autoload_object_link.rb +0 -1
- data/lib/carray/autoload/autoload_object_pack.rb +0 -2
- data/lib/carray/autoload.rb +0 -141
- data/lib/carray/basic.rb +0 -191
- data/lib/carray/broadcast.rb +0 -101
- data/lib/carray/compose.rb +0 -315
- data/lib/carray/convert.rb +0 -115
- data/lib/carray/info.rb +0 -110
- data/lib/carray/io/imagemagick.rb +0 -235
- data/lib/carray/mask.rb +0 -102
- data/lib/carray/math/histogram.rb +0 -177
- data/lib/carray/math/recurrence.rb +0 -93
- data/lib/carray/object/ca_obj_iterator.rb +0 -50
- data/lib/carray/object/ca_obj_link.rb +0 -50
- data/lib/carray/object/ca_obj_pack.rb +0 -99
- data/lib/carray/obsolete.rb +0 -256
- data/lib/carray/ordering.rb +0 -181
- data/lib/carray/testing.rb +0 -51
- data/lib/carray/transform.rb +0 -109
- data/misc/Methods.ja.md +0 -182
- data/misc/NOTE +0 -51
- data/spec/Classes/CABitfield_spec.rb +0 -58
- data/spec/Classes/CABlockIterator_spec.rb +0 -114
- data/spec/Classes/CABlock_spec.rb +0 -205
- data/spec/Classes/CAField_spec.rb +0 -39
- data/spec/Classes/CAGrid_spec.rb +0 -75
- data/spec/Classes/CAMap_spec.rb +0 -0
- data/spec/Classes/CAMapping_spec.rb +0 -105
- data/spec/Classes/CAObject_attribute_spec.rb +0 -33
- data/spec/Classes/CAObject_spec.rb +0 -33
- data/spec/Classes/CARefer_spec.rb +0 -93
- data/spec/Classes/CARepeat_spec.rb +0 -65
- data/spec/Classes/CASelect_spec.rb +0 -22
- data/spec/Classes/CAShift_spec.rb +0 -16
- data/spec/Classes/CAStruct_spec.rb +0 -71
- data/spec/Classes/CATranspose_spec.rb +0 -60
- data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
- data/spec/Classes/CAWindow_spec.rb +0 -54
- data/spec/Classes/CAWrap_spec.rb +0 -8
- data/spec/Classes/CArray_spec.rb +0 -184
- data/spec/Classes/CScalar_spec.rb +0 -55
- data/spec/Classes/ex1.rb +0 -46
- data/spec/Features/feature_130_spec.rb +0 -19
- data/spec/Features/feature_attributes_spec.rb +0 -280
- data/spec/Features/feature_boolean_spec.rb +0 -98
- data/spec/Features/feature_broadcast.rb +0 -116
- data/spec/Features/feature_cast_function.rb +0 -19
- data/spec/Features/feature_cast_spec.rb +0 -33
- data/spec/Features/feature_class_spec.rb +0 -84
- data/spec/Features/feature_complex_spec.rb +0 -42
- data/spec/Features/feature_composite_spec.rb +0 -124
- data/spec/Features/feature_convert_spec.rb +0 -46
- data/spec/Features/feature_copy_spec.rb +0 -123
- data/spec/Features/feature_creation_spec.rb +0 -84
- data/spec/Features/feature_element_spec.rb +0 -144
- data/spec/Features/feature_extream_spec.rb +0 -54
- data/spec/Features/feature_generate_spec.rb +0 -74
- data/spec/Features/feature_index_spec.rb +0 -69
- data/spec/Features/feature_mask_spec.rb +0 -580
- data/spec/Features/feature_math_spec.rb +0 -97
- data/spec/Features/feature_order_spec.rb +0 -146
- data/spec/Features/feature_ref_store_spec.rb +0 -209
- data/spec/Features/feature_serialization_spec.rb +0 -125
- data/spec/Features/feature_stat_spec.rb +0 -397
- data/spec/Features/feature_virtual_spec.rb +0 -48
- data/spec/Features/method_eq_spec.rb +0 -81
- data/spec/Features/method_is_nan_spec.rb +0 -12
- data/spec/Features/method_map_spec.rb +0 -54
- data/spec/Features/method_max_with.rb +0 -20
- data/spec/Features/method_min_with.rb +0 -19
- data/spec/Features/method_ne_spec.rb +0 -18
- data/spec/Features/method_project_spec.rb +0 -188
- data/spec/Features/method_ref_spec.rb +0 -27
- data/spec/Features/method_round_spec.rb +0 -11
- data/spec/Features/method_s_linspace_spec.rb +0 -48
- data/spec/Features/method_s_span_spec.rb +0 -14
- data/spec/Features/method_seq_spec.rb +0 -47
- data/spec/Features/method_sort_with.rb +0 -43
- data/spec/Features/method_sorted_with.rb +0 -29
- data/spec/Features/method_span_spec.rb +0 -42
- data/spec/Features/method_wrap_readonly_spec.rb +0 -43
- data/spec/UnitTest/test_CAVirtual.rb +0 -214
- data/spec/spec_all.rb +0 -10
- data/utils/ca_ase.rb +0 -21
- data/utils/ca_methods.rb +0 -15
- data/utils/cast_checker.rb +0 -30
- data/utils/convert_test.rb +0 -73
- data/utils/extract_yard.rb +0 -22
- data/utils/guess_shape.rb +0 -76
- data/utils/monkey_patch_methods.rb +0 -62
- data/utils/remove_resource_fork.sh +0 -5
data/ext/ca_obj_shift.c
CHANGED
|
@@ -1,59 +1,60 @@
|
|
|
1
1
|
/* ---------------------------------------------------------------------------
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
CAShift is a pure typedef of CAWindow (see carray.h). CAShift
|
|
4
|
+
construction maps (shift[], roll[], fill, fill_mask) onto CAWindow's
|
|
5
|
+
(start = -shift, count = parent->dim, bounds = roll ? PERIODIC :
|
|
6
|
+
(fill_mask ? MASK : FILL), fill) via ca_window_setup, then bumps
|
|
7
|
+
obj_type to CA_OBJ_SHIFT. Operations (attach / sync / copy_data /
|
|
8
|
+
sync_data / fill_data / ptr_at_* / fetch_index / store_index) are
|
|
9
|
+
shared with CAWindow's per-axis bounds engine via the `ca_shift_func`
|
|
10
|
+
table, which is built by copying `ca_window_func` and only overriding
|
|
11
|
+
free / clone / create_mask so that CAShift-typed instances are produced
|
|
12
|
+
on cloning and mask-projection.
|
|
13
|
+
|
|
14
|
+
User surface (CArray#shift) is documented in yard-stubs/ca_obj_shift.rb.
|
|
8
15
|
|
|
9
16
|
---------------------------------------------------------------------------- */
|
|
10
17
|
|
|
11
18
|
#include "carray.h"
|
|
19
|
+
#include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
|
|
12
20
|
|
|
13
|
-
/*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
ca_size_t *dim;
|
|
26
|
-
char *ptr;
|
|
27
|
-
CArray *mask;
|
|
28
|
-
CArray *parent;
|
|
29
|
-
uint32_t attach;
|
|
30
|
-
uint8_t nosync;
|
|
31
|
-
/* -------------*/
|
|
32
|
-
ca_size_t *shift;
|
|
33
|
-
char *fill;
|
|
34
|
-
int8_t *roll;
|
|
35
|
-
int fill_mask;
|
|
36
|
-
} CAShift;
|
|
21
|
+
/* External: CAWindow's operation table + setup are the basis for CAShift. */
|
|
22
|
+
extern ca_operation_function_t ca_window_func;
|
|
23
|
+
extern VALUE rb_cCAWindow;
|
|
24
|
+
extern int ca_window_setup (CAWindow *ca, CArray *parent,
|
|
25
|
+
ca_size_t *start, ca_size_t *count,
|
|
26
|
+
uint8_t *bounds, char *fill);
|
|
27
|
+
|
|
28
|
+
/* CAShift dsize: same formula as CAWindow (the structs share layout).
|
|
29
|
+
CAREFUL: forward-declared so the const rb_data_type_t initialisers
|
|
30
|
+
below can reference it. Patching dsize into the table in Init via a
|
|
31
|
+
(rb_data_type_t *) cast would write into .rodata and SIGBUS on macOS. */
|
|
32
|
+
static size_t ca_shift_dsize (const void *ap);
|
|
37
33
|
|
|
38
34
|
const rb_data_type_t cashift_data_type = {
|
|
39
|
-
.parent = &
|
|
35
|
+
.parent = &caview_data_type,
|
|
40
36
|
.wrap_struct_name = "CAShift",
|
|
41
37
|
.function = {
|
|
42
38
|
.dmark = ca_mark,
|
|
43
39
|
.dfree = ca_free,
|
|
44
|
-
.dsize =
|
|
40
|
+
.dsize = ca_shift_dsize,
|
|
45
41
|
.dcompact = NULL
|
|
46
42
|
},
|
|
47
43
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
48
44
|
};
|
|
49
45
|
|
|
46
|
+
/* CAREFUL: mask TypedData uses ca_free_nop. The mask CArray is owned
|
|
47
|
+
by the parent CAShift's `ca->mask` field and freed by free_ca_shift's
|
|
48
|
+
ca_free(ca->mask). If the wrapped Ruby VALUE (from the `ca.mask`
|
|
49
|
+
accessor / rb_ca_mask_array) also freed it, the result is a
|
|
50
|
+
double-free that explodes under GC stress. */
|
|
50
51
|
const rb_data_type_t cashift_mask_data_type = {
|
|
51
52
|
.parent = &cashift_data_type,
|
|
52
|
-
.wrap_struct_name = "
|
|
53
|
+
.wrap_struct_name = "CAShiftMask",
|
|
53
54
|
.function = {
|
|
54
55
|
.dmark = ca_mark,
|
|
55
|
-
.dfree =
|
|
56
|
-
.dsize =
|
|
56
|
+
.dfree = ca_free_nop,
|
|
57
|
+
.dsize = ca_shift_dsize,
|
|
57
58
|
.dcompact = NULL
|
|
58
59
|
},
|
|
59
60
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
@@ -64,800 +65,202 @@ static int8_t CA_OBJ_SHIFT;
|
|
|
64
65
|
VALUE rb_cCAShift;
|
|
65
66
|
VALUE rb_cCAShiftMask;
|
|
66
67
|
|
|
68
|
+
/* Custom op table for CAShift — populated in Init from ca_window_func. */
|
|
69
|
+
static ca_operation_function_t ca_shift_func;
|
|
70
|
+
|
|
71
|
+
/* CAShift dsize: same formula as CAWindow (same struct layout). */
|
|
72
|
+
static size_t
|
|
73
|
+
ca_shift_dsize (const void *ap)
|
|
74
|
+
{
|
|
75
|
+
const CAShift *ca = (const CAShift *) ap;
|
|
76
|
+
return sizeof(CAShift) + 3 * ca->ndim * sizeof(ca_size_t)
|
|
77
|
+
+ ca->ndim * sizeof(uint8_t) + ca->bytes;
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
/* ------------------------------------------------------------------- */
|
|
68
81
|
|
|
69
82
|
int
|
|
70
83
|
ca_shift_setup (CAShift *ca, CArray *parent,
|
|
71
|
-
|
|
84
|
+
ca_size_t *shift, char *fill, int8_t *roll, int fill_mask)
|
|
72
85
|
{
|
|
73
|
-
|
|
74
|
-
ca_size_t
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
ndim
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
ca
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
memcpy(ca->shift, shift, ndim * sizeof(ca_size_t));
|
|
101
|
-
memcpy(ca->roll, roll, ndim * sizeof(int8_t));
|
|
102
|
-
|
|
103
|
-
if ( fill ) {
|
|
104
|
-
ca->fill_mask = 0;
|
|
105
|
-
memcpy(ca->fill, fill, ca->bytes);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
ca->fill_mask = 1;
|
|
109
|
-
memset(ca->fill, 0, ca->bytes);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if ( ca_has_mask(parent) ) {
|
|
113
|
-
ca_create_mask(ca);
|
|
114
|
-
}
|
|
86
|
+
ca_size_t start[CA_RANK_MAX];
|
|
87
|
+
ca_size_t count[CA_RANK_MAX];
|
|
88
|
+
uint8_t bounds[CA_RANK_MAX];
|
|
89
|
+
int8_t k, ndim;
|
|
90
|
+
|
|
91
|
+
ndim = parent->ndim;
|
|
92
|
+
CA_ASSUME(ndim >= 0 && ndim <= CA_RANK_MAX); /* bound loop over [CA_RANK_MAX] arrays */
|
|
93
|
+
for (k = 0; k < ndim; k++) {
|
|
94
|
+
start[k] = -shift[k];
|
|
95
|
+
count[k] = parent->dim[k];
|
|
96
|
+
if ( roll[k] ) {
|
|
97
|
+
bounds[k] = CA_BOUNDS_PERIODIC;
|
|
98
|
+
} else if ( fill_mask ) {
|
|
99
|
+
bounds[k] = CA_BOUNDS_MASK;
|
|
100
|
+
} else {
|
|
101
|
+
bounds[k] = CA_BOUNDS_FILL;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Delegate to CAWindow setup. */
|
|
106
|
+
ca_window_setup((CAWindow *) ca, parent, start, count, bounds, fill);
|
|
107
|
+
|
|
108
|
+
/* Override obj_type so dispatch (ca_func[obj_type]) lands on the
|
|
109
|
+
CAShift-specific table (which differs from CAWindow only in
|
|
110
|
+
free / clone / create_mask, all forwarding to a CAShift-typed
|
|
111
|
+
result). */
|
|
112
|
+
ca->obj_type = CA_OBJ_SHIFT;
|
|
115
113
|
|
|
116
114
|
return 0;
|
|
117
115
|
}
|
|
118
116
|
|
|
119
117
|
CAShift *
|
|
120
|
-
ca_shift_new (CArray *parent, ca_size_t *shift, char *fill, int8_t *roll
|
|
118
|
+
ca_shift_new (CArray *parent, ca_size_t *shift, char *fill, int8_t *roll,
|
|
119
|
+
int fill_mask)
|
|
121
120
|
{
|
|
122
|
-
CAShift *ca =
|
|
123
|
-
ca_shift_setup(ca, parent, shift, fill, roll);
|
|
121
|
+
CAShift *ca = (CAShift *) ca_array_alloc(CA_OBJ_SHIFT, parent->ndim);
|
|
122
|
+
ca_shift_setup(ca, parent, shift, fill, roll, fill_mask);
|
|
124
123
|
return ca;
|
|
125
124
|
}
|
|
126
125
|
|
|
126
|
+
/* Free: same fields as CAWindow (same struct). CAShift goes through
|
|
127
|
+
ca_window_setup, so the same seven ndim-sized fields live in ca->_pool
|
|
128
|
+
(fill stays separate). */
|
|
127
129
|
static void
|
|
128
130
|
free_ca_shift (void *ap)
|
|
129
131
|
{
|
|
130
132
|
CAShift *ca = (CAShift *) ap;
|
|
131
133
|
if ( ca != NULL ) {
|
|
132
|
-
xfree(ca->fill);
|
|
133
|
-
xfree(ca->shift);
|
|
134
|
-
xfree(ca->roll);
|
|
135
134
|
ca_free(ca->mask);
|
|
136
|
-
xfree(ca->
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
static void ca_shift_attach (CAShift *ca);
|
|
142
|
-
static void ca_shift_sync (CAShift *ca);
|
|
143
|
-
static void ca_shift_fill (CAShift *ca, char *ptr);
|
|
144
|
-
|
|
145
|
-
static ca_size_t
|
|
146
|
-
ca_shift_normalized_roll_shift (CAShift *ca, ca_size_t i)
|
|
147
|
-
{
|
|
148
|
-
ca_size_t dim = ca->dim[i];
|
|
149
|
-
ca_size_t shift = ca->shift[i];
|
|
150
|
-
if ( shift >= 0 ) {
|
|
151
|
-
return shift % dim;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
return -((-shift) % dim);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
static ca_size_t
|
|
159
|
-
ca_shift_rolled_index (CAShift *ca, ca_size_t i, ca_size_t k)
|
|
160
|
-
{
|
|
161
|
-
ca_size_t dim = ca->dim[i];
|
|
162
|
-
ca_size_t shift = ca->shift[i];
|
|
163
|
-
ca_size_t idx = k - shift;
|
|
164
|
-
if ( idx >= 0 ) {
|
|
165
|
-
return idx % dim;
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
idx = (-idx) % dim;
|
|
169
|
-
return ( ! idx ) ? 0 : dim - idx;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
static ca_size_t
|
|
174
|
-
ca_shift_shifted_index (CAShift *ca, ca_size_t i, ca_size_t k)
|
|
175
|
-
{
|
|
176
|
-
ca_size_t dim = ca->dim[i];
|
|
177
|
-
ca_size_t shift = ca->shift[i];
|
|
178
|
-
ca_size_t idx = k - shift;
|
|
179
|
-
if ( idx < 0 || idx >= dim ) {
|
|
180
|
-
return -1;
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
return idx;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/* ------------------------------------------------------------------- */
|
|
188
|
-
|
|
189
|
-
static void *
|
|
190
|
-
ca_shift_func_clone (void *ap)
|
|
191
|
-
{
|
|
192
|
-
CAShift *ca = (CAShift *) ap;
|
|
193
|
-
return ca_shift_new(ca->parent, ca->shift, ca->fill, ca->roll);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
static char *
|
|
197
|
-
ca_shift_func_ptr_at_addr (void *ap, ca_size_t addr)
|
|
198
|
-
{
|
|
199
|
-
CAShift *ca = (CAShift *) ap;
|
|
200
|
-
if ( ! ca->ptr ) {
|
|
201
|
-
ca_size_t idx[CA_RANK_MAX];
|
|
202
|
-
ca_addr2index((CArray *)ca, addr, idx);
|
|
203
|
-
return ca_ptr_at_index(ca, idx);
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
return ca->ptr + ca->bytes * addr;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
static char *
|
|
211
|
-
ca_shift_func_ptr_at_index (void *ap, ca_size_t *idx)
|
|
212
|
-
{
|
|
213
|
-
CAShift *ca = (CAShift *) ap;
|
|
214
|
-
if ( ! ca->ptr ) {
|
|
215
|
-
ca_size_t *dim = ca->dim;
|
|
216
|
-
int8_t *roll = ca->roll;
|
|
217
|
-
int8_t i;
|
|
218
|
-
ca_size_t k, n;
|
|
219
|
-
n = 0;
|
|
220
|
-
for (i=0; i<ca->ndim; i++) {
|
|
221
|
-
k = idx[i];
|
|
222
|
-
if ( roll[i] ) {
|
|
223
|
-
k = ca_shift_rolled_index(ca, i, k);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
k = ca_shift_shifted_index(ca, i, k);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if ( k < 0 ) {
|
|
230
|
-
return ca->fill;
|
|
231
|
-
}
|
|
232
|
-
n = dim[i] * n + k;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if ( ca->parent->ptr == NULL ) {
|
|
236
|
-
return ca_ptr_at_addr(ca->parent, n);
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
return ca->parent->ptr + ca->bytes * n;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
return ca_func[CA_OBJ_ARRAY].ptr_at_index(ca, idx);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
static void
|
|
248
|
-
ca_shift_func_fetch_index (void *ap, ca_size_t *idx, void *ptr)
|
|
249
|
-
{
|
|
250
|
-
CAShift *ca = (CAShift *) ap;
|
|
251
|
-
ca_size_t *dim = ca->dim;
|
|
252
|
-
int8_t *roll = ca->roll;
|
|
253
|
-
int8_t i;
|
|
254
|
-
ca_size_t k, n;
|
|
255
|
-
n = 0;
|
|
256
|
-
for (i=0; i<ca->ndim; i++) {
|
|
257
|
-
k = idx[i];
|
|
258
|
-
if ( roll[i] ) {
|
|
259
|
-
k = ca_shift_rolled_index(ca, i, k);
|
|
135
|
+
xfree(ca->fill); /* always separate (bytes-sized) */
|
|
136
|
+
if ( ca->_pool ) {
|
|
137
|
+
ca_array_free(ca);
|
|
260
138
|
}
|
|
261
139
|
else {
|
|
262
|
-
|
|
140
|
+
xfree(ca->bounds);
|
|
141
|
+
xfree(ca->start);
|
|
142
|
+
xfree(ca->count);
|
|
143
|
+
xfree(ca->size0);
|
|
144
|
+
xfree(ca->embed_parent_start);
|
|
145
|
+
xfree(ca->embed_count);
|
|
146
|
+
xfree(ca->embed_output_offset);
|
|
147
|
+
xfree(ca);
|
|
263
148
|
}
|
|
264
|
-
|
|
265
|
-
if ( k < 0 ) {
|
|
266
|
-
memcpy(ptr, ca->fill, ca->bytes);
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
n = dim[i] * n + k;
|
|
270
149
|
}
|
|
271
|
-
ca_fetch_addr(ca->parent, n, ptr);
|
|
272
150
|
}
|
|
273
151
|
|
|
274
|
-
|
|
275
|
-
|
|
152
|
+
/* Clone: produce a CAShift (not CAWindow) by rebuilding via setup.
|
|
153
|
+
Recover (shift[], roll[], fill_mask) from current (start[], bounds[]). */
|
|
154
|
+
static void *
|
|
155
|
+
ca_shift_func_clone (void *ap)
|
|
276
156
|
{
|
|
277
157
|
CAShift *ca = (CAShift *) ap;
|
|
278
|
-
ca_size_t
|
|
279
|
-
int8_t
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
n = 0;
|
|
283
|
-
for (i=0; i<ca->ndim; i++) {
|
|
284
|
-
k = idx[i];
|
|
285
|
-
if ( roll[i] ) {
|
|
286
|
-
k = ca_shift_rolled_index(ca, i, k);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
k = ca_shift_shifted_index(ca, i, k);
|
|
290
|
-
}
|
|
158
|
+
ca_size_t shift[CA_RANK_MAX];
|
|
159
|
+
int8_t roll[CA_RANK_MAX];
|
|
160
|
+
int fill_mask = 0;
|
|
161
|
+
int8_t k;
|
|
291
162
|
|
|
292
|
-
|
|
293
|
-
|
|
163
|
+
/* shift[k] = -start[k] (inverse of setup's start = -shift) */
|
|
164
|
+
for (k = 0; k < ca->ndim; k++) {
|
|
165
|
+
shift[k] = -ca->start[k];
|
|
166
|
+
if ( ca->bounds[k] == CA_BOUNDS_PERIODIC ) {
|
|
167
|
+
roll[k] = 1;
|
|
168
|
+
} else {
|
|
169
|
+
roll[k] = 0;
|
|
170
|
+
if ( ca->bounds[k] == CA_BOUNDS_MASK ) fill_mask = 1;
|
|
294
171
|
}
|
|
295
|
-
n = dim[i] * n + k;
|
|
296
172
|
}
|
|
297
|
-
ca_store_addr(ca->parent, n, ptr);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
static void
|
|
301
|
-
ca_shift_func_allocate (void *ap)
|
|
302
|
-
{
|
|
303
|
-
CAShift *ca = (CAShift *) ap;
|
|
304
|
-
ca_attach(ca->parent);
|
|
305
|
-
/* ca->ptr = ALLOC_N(char, ca_length(ca)); */
|
|
306
|
-
ca->ptr = malloc_with_check(ca_length(ca));
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
static void
|
|
310
|
-
ca_shift_func_attach (void *ap)
|
|
311
|
-
{
|
|
312
|
-
void ca_shift_attach (CAShift *cb);
|
|
313
|
-
|
|
314
|
-
CAShift *ca = (CAShift *) ap;
|
|
315
|
-
ca_attach(ca->parent);
|
|
316
|
-
/* ca->ptr = ALLOC_N(char, ca_length(ca)); */
|
|
317
|
-
ca->ptr = malloc_with_check(ca_length(ca));
|
|
318
|
-
ca_shift_attach(ca);
|
|
319
|
-
}
|
|
320
173
|
|
|
321
|
-
|
|
322
|
-
ca_shift_func_sync (void *ap)
|
|
323
|
-
{
|
|
324
|
-
CAShift *ca = (CAShift *) ap;
|
|
325
|
-
ca_shift_sync(ca);
|
|
326
|
-
ca_sync(ca->parent);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
static void
|
|
330
|
-
ca_shift_func_detach (void *ap)
|
|
331
|
-
{
|
|
332
|
-
CAShift *ca = (CAShift *) ap;
|
|
333
|
-
free(ca->ptr);
|
|
334
|
-
ca->ptr = NULL;
|
|
335
|
-
ca_detach(ca->parent);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
static void
|
|
339
|
-
ca_shift_func_copy_data (void *ap, void *ptr)
|
|
340
|
-
{
|
|
341
|
-
CAShift *ca = (CAShift *) ap;
|
|
342
|
-
char *ptr0 = ca->ptr;
|
|
343
|
-
ca_attach(ca->parent);
|
|
344
|
-
ca->ptr = ptr;
|
|
345
|
-
ca_shift_attach(ca);
|
|
346
|
-
ca->ptr = ptr0;
|
|
347
|
-
ca_detach(ca->parent);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
static void
|
|
351
|
-
ca_shift_func_sync_data (void *ap, void *ptr)
|
|
352
|
-
{
|
|
353
|
-
CAShift *ca = (CAShift *) ap;
|
|
354
|
-
char *ptr0 = ca->ptr;
|
|
355
|
-
ca_attach(ca->parent);
|
|
356
|
-
ca->ptr = ptr;
|
|
357
|
-
ca_shift_sync(ca);
|
|
358
|
-
ca->ptr = ptr0;
|
|
359
|
-
ca_sync(ca->parent);
|
|
360
|
-
ca_detach(ca->parent);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
static void
|
|
364
|
-
ca_shift_func_fill_data (void *ap, void *ptr)
|
|
365
|
-
{
|
|
366
|
-
CAShift *ca = (CAShift *) ap;
|
|
367
|
-
ca_attach(ca->parent);
|
|
368
|
-
ca_shift_fill(ca, ptr);
|
|
369
|
-
ca_sync(ca->parent);
|
|
370
|
-
ca_detach(ca->parent);
|
|
174
|
+
return ca_shift_new(ca->parent, shift, ca->fill, roll, fill_mask);
|
|
371
175
|
}
|
|
372
176
|
|
|
177
|
+
/* create_mask: produce a CAShift-typed mask (not CAWindow-typed).
|
|
178
|
+
Following the original ca_shift_func_create_mask semantics:
|
|
179
|
+
- Ensure parent has mask
|
|
180
|
+
- Build mask sub-view using same shift/roll, fill = 1 if fill_mask
|
|
181
|
+
else 0 (i.e. range-outside cells get masked when fill_mask was on,
|
|
182
|
+
unmasked otherwise) */
|
|
373
183
|
static void
|
|
374
184
|
ca_shift_func_create_mask (void *ap)
|
|
375
185
|
{
|
|
376
186
|
CAShift *ca = (CAShift *) ap;
|
|
377
|
-
|
|
378
|
-
|
|
187
|
+
ca_size_t shift[CA_RANK_MAX];
|
|
188
|
+
int8_t roll[CA_RANK_MAX];
|
|
189
|
+
boolean8_t fill_val;
|
|
190
|
+
int fill_mask_was_on = 0;
|
|
191
|
+
int8_t k;
|
|
379
192
|
|
|
380
193
|
ca_update_mask(ca->parent);
|
|
381
|
-
|
|
382
194
|
if ( ! ca->parent->mask ) {
|
|
383
195
|
ca_create_mask(ca->parent);
|
|
384
196
|
}
|
|
385
197
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
198
|
+
for (k = 0; k < ca->ndim; k++) {
|
|
199
|
+
shift[k] = -ca->start[k];
|
|
200
|
+
if ( ca->bounds[k] == CA_BOUNDS_PERIODIC ) {
|
|
201
|
+
roll[k] = 1;
|
|
202
|
+
} else {
|
|
203
|
+
roll[k] = 0;
|
|
204
|
+
if ( ca->bounds[k] == CA_BOUNDS_MASK ) fill_mask_was_on = 1;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* If MASK policy was set, the mask sub-view should mark out-of-range
|
|
209
|
+
cells as "masked" (fill value = 1). Otherwise out-of-range cells
|
|
210
|
+
get the fill value (fill = 0) and aren't masked. */
|
|
211
|
+
fill_val = fill_mask_was_on ? 1 : 0;
|
|
212
|
+
|
|
213
|
+
/* Build the mask as CAShift with same shift/roll but using fill_mask=0
|
|
214
|
+
(the mask itself shouldn't recursively create a mask) and fill = 0/1
|
|
215
|
+
boolean. Bounds for mask: replace MASK→FILL so the mask values are
|
|
216
|
+
written, not the mask's mask. */
|
|
217
|
+
{
|
|
218
|
+
/* Construct mask via direct ca_window_new with adjusted bounds. */
|
|
219
|
+
uint8_t mbounds[CA_RANK_MAX];
|
|
220
|
+
ca_size_t mstart[CA_RANK_MAX];
|
|
221
|
+
ca_size_t mcount[CA_RANK_MAX];
|
|
222
|
+
CAShift *m;
|
|
223
|
+
CA_ASSUME(ca->ndim >= 0 && ca->ndim <= CA_RANK_MAX); /* bound loop over [CA_RANK_MAX] arrays */
|
|
224
|
+
for (k = 0; k < ca->ndim; k++) {
|
|
225
|
+
mstart[k] = ca->start[k];
|
|
226
|
+
mcount[k] = ca->count[k];
|
|
227
|
+
mbounds[k] = ( ca->bounds[k] == CA_BOUNDS_MASK )
|
|
228
|
+
? CA_BOUNDS_FILL : ca->bounds[k];
|
|
229
|
+
}
|
|
230
|
+
/* CAShift-typed mask: allocate, setup as CAWindow with adjusted
|
|
231
|
+
bounds, bump obj_type. */
|
|
232
|
+
m = (CAShift *) ca_array_alloc(CA_OBJ_SHIFT, ca->ndim);
|
|
233
|
+
ca_window_setup((CAWindow *) m, ca->parent->mask,
|
|
234
|
+
mstart, mcount, mbounds, (char *) &fill_val);
|
|
235
|
+
m->obj_type = CA_OBJ_SHIFT;
|
|
236
|
+
ca->mask = (CArray *) m;
|
|
237
|
+
}
|
|
238
|
+
(void) shift; (void) roll; /* recovered above but unused in this block */
|
|
394
239
|
}
|
|
395
240
|
|
|
396
|
-
ca_operation_function_t ca_shift_func = {
|
|
397
|
-
-1, /* CA_OBJ_SHIFT */
|
|
398
|
-
CA_VIRTUAL_ARRAY,
|
|
399
|
-
free_ca_shift,
|
|
400
|
-
ca_shift_func_clone,
|
|
401
|
-
ca_shift_func_ptr_at_addr,
|
|
402
|
-
ca_shift_func_ptr_at_index,
|
|
403
|
-
NULL,
|
|
404
|
-
ca_shift_func_fetch_index,
|
|
405
|
-
NULL,
|
|
406
|
-
ca_shift_func_store_index,
|
|
407
|
-
ca_shift_func_allocate,
|
|
408
|
-
ca_shift_func_attach,
|
|
409
|
-
ca_shift_func_sync,
|
|
410
|
-
ca_shift_func_detach,
|
|
411
|
-
ca_shift_func_copy_data,
|
|
412
|
-
ca_shift_func_sync_data,
|
|
413
|
-
ca_shift_func_fill_data,
|
|
414
|
-
ca_shift_func_create_mask,
|
|
415
|
-
};
|
|
416
|
-
|
|
417
241
|
/* ------------------------------------------------------------------- */
|
|
418
242
|
|
|
419
|
-
static void
|
|
420
|
-
ca_shift_attach_loop (CAShift *ca, int16_t level, ca_size_t *idx, ca_size_t *idx0,
|
|
421
|
-
int32_t fill)
|
|
422
|
-
{
|
|
423
|
-
ca_size_t dim = ca->dim[level];
|
|
424
|
-
ca_size_t shift = ca->shift[level];
|
|
425
|
-
int8_t roll = ca->roll[level];
|
|
426
|
-
ca_size_t i;
|
|
427
|
-
|
|
428
|
-
if ( level == ca->ndim - 1 ) {
|
|
429
|
-
if ( fill ) {
|
|
430
|
-
for (i=0; i<ca->dim[level]; i++) {
|
|
431
|
-
idx[level] = i;
|
|
432
|
-
memcpy(ca_ptr_at_index(ca, idx), ca->fill, ca->bytes);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
else if ( ! shift ) {
|
|
436
|
-
idx[level] = 0;
|
|
437
|
-
idx0[level] = 0;
|
|
438
|
-
memcpy(ca_ptr_at_index(ca, idx), ca_ptr_at_index(ca->parent, idx0), dim * ca->bytes);
|
|
439
|
-
}
|
|
440
|
-
else if ( roll ) {
|
|
441
|
-
shift = ca_shift_normalized_roll_shift(ca, level);
|
|
442
|
-
if ( shift > 0 ) {
|
|
443
|
-
idx[level] = 0;
|
|
444
|
-
idx0[level] = dim-shift;
|
|
445
|
-
memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), shift*ca->bytes);
|
|
446
|
-
idx[level] = shift;
|
|
447
|
-
idx0[level] = 0;
|
|
448
|
-
memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), (dim-shift)*ca->bytes);
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
idx[level] = 0;
|
|
452
|
-
idx0[level] = -shift;
|
|
453
|
-
memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), (dim+shift)*ca->bytes);
|
|
454
|
-
idx[level] = dim + shift;
|
|
455
|
-
idx0[level] = 0;
|
|
456
|
-
memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), (-shift)*ca->bytes);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
else {
|
|
460
|
-
if ( shift > 0 ) {
|
|
461
|
-
shift = ( shift >= dim ) ? dim : shift;
|
|
462
|
-
|
|
463
|
-
for (i=0; i<shift; i++) {
|
|
464
|
-
idx[level] = i;
|
|
465
|
-
memcpy(ca_ptr_at_index(ca, idx), ca->fill, ca->bytes);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
if ( shift < dim ) {
|
|
469
|
-
idx[level] = shift;
|
|
470
|
-
idx0[level] = 0;
|
|
471
|
-
memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0),(dim-shift)*ca->bytes);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
else {
|
|
475
|
-
shift = ( -shift >= dim ) ? -dim : shift;
|
|
476
|
-
|
|
477
|
-
if ( -shift < dim ) {
|
|
478
|
-
idx[level] = 0;
|
|
479
|
-
idx0[level] = -shift;
|
|
480
|
-
memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0),(dim+shift)*ca->bytes);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
for (i=0; i<-shift; i++) {
|
|
484
|
-
idx[level] = dim+shift+i;
|
|
485
|
-
memcpy(ca_ptr_at_index(ca, idx), ca->fill, ca->bytes);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
else {
|
|
491
|
-
if ( fill ) {
|
|
492
|
-
for (i=0; i<dim; i++) {
|
|
493
|
-
idx[level] = i;
|
|
494
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 1); /* fill */
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
else if ( ! shift ) {
|
|
498
|
-
for (i=0; i<dim; i++) {
|
|
499
|
-
idx[level] = i;
|
|
500
|
-
idx0[level] = i;
|
|
501
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
else if ( roll ) {
|
|
505
|
-
shift = ca_shift_normalized_roll_shift(ca, level);
|
|
506
|
-
|
|
507
|
-
if ( shift > 0 ) {
|
|
508
|
-
for (i=0; i<shift; i++) {
|
|
509
|
-
idx[level] = i;
|
|
510
|
-
idx0[level] = dim-shift+i;
|
|
511
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
for (i=0; i<dim-shift; i++) {
|
|
515
|
-
idx[level] = shift+i;
|
|
516
|
-
idx0[level] = i;
|
|
517
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
else {
|
|
521
|
-
for (i=0; i<dim+shift; i++) {
|
|
522
|
-
idx[level] = i;
|
|
523
|
-
idx0[level] = -shift+i;
|
|
524
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
for (i=0; i<-shift; i++) {
|
|
528
|
-
idx[level] = dim + shift + i;
|
|
529
|
-
idx0[level] = i;
|
|
530
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
else {
|
|
535
|
-
if ( shift > 0 ) {
|
|
536
|
-
shift = ( shift >= dim ) ? dim : shift;
|
|
537
|
-
|
|
538
|
-
for (i=0; i<shift; i++) {
|
|
539
|
-
idx[level] = i;
|
|
540
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 1); /* fill */
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
if ( shift < dim ) {
|
|
544
|
-
for (i=0; i<dim-shift; i++) {
|
|
545
|
-
idx[level] = shift+i;
|
|
546
|
-
idx0[level] = i;
|
|
547
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
else {
|
|
552
|
-
shift = ( -shift >= dim ) ? -dim : shift;
|
|
553
|
-
|
|
554
|
-
if ( -shift < dim ) {
|
|
555
|
-
for (i=0; i<dim+shift; i++) {
|
|
556
|
-
idx[level] = i;
|
|
557
|
-
idx0[level] = -shift+i;
|
|
558
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
for (i=0; i<-shift; i++) {
|
|
563
|
-
idx[level] = dim+shift+i;
|
|
564
|
-
ca_shift_attach_loop(ca, level+1, idx, idx0, 1); /* fill */
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
static void
|
|
572
|
-
ca_shift_attach (CAShift *ca)
|
|
573
|
-
{
|
|
574
|
-
ca_size_t idx[CA_RANK_MAX];
|
|
575
|
-
ca_size_t idx0[CA_RANK_MAX];
|
|
576
|
-
ca_shift_attach_loop(ca, (int16_t) 0, idx, idx0, 0);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
static void
|
|
580
|
-
ca_shift_sync_loop (CAShift *ca, int16_t level, ca_size_t *idx, ca_size_t *idx0)
|
|
581
|
-
{
|
|
582
|
-
ca_size_t dim = ca->dim[level];
|
|
583
|
-
ca_size_t shift = ca->shift[level];
|
|
584
|
-
int8_t roll = ca->roll[level];
|
|
585
|
-
ca_size_t i;
|
|
586
|
-
|
|
587
|
-
if ( level == ca->ndim - 1 ) {
|
|
588
|
-
if ( ! shift ) {
|
|
589
|
-
idx[level] = 0;
|
|
590
|
-
idx0[level] = 0;
|
|
591
|
-
memcpy(ca_ptr_at_index(ca->parent, idx0), ca_ptr_at_index(ca, idx), dim * ca->bytes);
|
|
592
|
-
}
|
|
593
|
-
else if ( roll ) {
|
|
594
|
-
shift = ca_shift_normalized_roll_shift(ca, level);
|
|
595
|
-
|
|
596
|
-
if ( shift > 0 ) {
|
|
597
|
-
idx[level] = 0;
|
|
598
|
-
idx0[level] = dim-shift;
|
|
599
|
-
memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), shift*ca->bytes);
|
|
600
|
-
idx[level] = shift;
|
|
601
|
-
idx0[level] = 0;
|
|
602
|
-
memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), (dim-shift)*ca->bytes);
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
idx[level] = 0;
|
|
606
|
-
idx0[level] = -shift;
|
|
607
|
-
memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), (dim+shift)*ca->bytes);
|
|
608
|
-
idx[level] = dim + shift;
|
|
609
|
-
idx0[level] = 0;
|
|
610
|
-
memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), (-shift)*ca->bytes);
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
else {
|
|
614
|
-
if ( shift > 0 ) {
|
|
615
|
-
shift = ( shift >= dim ) ? dim : shift;
|
|
616
|
-
|
|
617
|
-
for (i=0; i<shift; i++) {
|
|
618
|
-
; /* do nothing */
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
if ( shift < dim ) {
|
|
622
|
-
idx[level] = shift;
|
|
623
|
-
idx0[level] = 0;
|
|
624
|
-
memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx),(dim-shift)*ca->bytes);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
else {
|
|
628
|
-
shift = ( -shift >= dim ) ? -dim : shift;
|
|
629
|
-
|
|
630
|
-
if ( -shift < dim ) {
|
|
631
|
-
idx[level] = 0;
|
|
632
|
-
idx0[level] = -shift;
|
|
633
|
-
memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx),(dim+shift)*ca->bytes);
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
for (i=0; i<-shift; i++) {
|
|
637
|
-
; /* do nothing */
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
else {
|
|
643
|
-
if ( ! shift ) {
|
|
644
|
-
for (i=0; i<dim; i++) {
|
|
645
|
-
idx[level] = i;
|
|
646
|
-
idx0[level] = i;
|
|
647
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
else if ( roll ) {
|
|
651
|
-
shift = ca_shift_normalized_roll_shift(ca, level);
|
|
652
|
-
if ( shift > 0 ) {
|
|
653
|
-
for (i=0; i<shift; i++) {
|
|
654
|
-
idx[level] = i;
|
|
655
|
-
idx0[level] = dim-shift+i;
|
|
656
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
for (i=0; i<dim-shift; i++) {
|
|
660
|
-
idx[level] = shift+i;
|
|
661
|
-
idx0[level] = i;
|
|
662
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
for (i=0; i<dim+shift; i++) {
|
|
667
|
-
idx[level] = i;
|
|
668
|
-
idx0[level] = -shift+i;
|
|
669
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
for (i=0; i<-shift; i++) {
|
|
673
|
-
idx[level] = dim + shift + i;
|
|
674
|
-
idx0[level] = i;
|
|
675
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
if ( shift > 0 ) {
|
|
681
|
-
shift = ( shift >= dim ) ? dim : shift;
|
|
682
|
-
|
|
683
|
-
for (i=0; i<shift; i++) {
|
|
684
|
-
; /* do nothing */
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
if ( shift < dim ) {
|
|
688
|
-
for (i=0; i<dim-shift; i++) {
|
|
689
|
-
idx[level] = shift+i;
|
|
690
|
-
idx0[level] = i;
|
|
691
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
else {
|
|
696
|
-
shift = ( -shift >= dim ) ? -dim : shift;
|
|
697
|
-
|
|
698
|
-
if ( -shift < dim ) {
|
|
699
|
-
for (i=0; i<dim+shift; i++) {
|
|
700
|
-
idx[level] = i;
|
|
701
|
-
idx0[level] = -shift+i;
|
|
702
|
-
ca_shift_sync_loop(ca, level+1, idx, idx0);
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
for (i=0; i<-shift; i++) {
|
|
707
|
-
; /* do nothing */
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
static void
|
|
715
|
-
ca_shift_sync (CAShift *ca)
|
|
716
|
-
{
|
|
717
|
-
ca_size_t idx[CA_RANK_MAX];
|
|
718
|
-
ca_size_t idx0[CA_RANK_MAX];
|
|
719
|
-
ca_shift_sync_loop(ca, (int16_t) 0, idx, idx0);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
static void
|
|
723
|
-
ca_shift_fill_loop (CAShift *ca, char *ptr,
|
|
724
|
-
int16_t level, ca_size_t *idx0)
|
|
725
|
-
{
|
|
726
|
-
ca_size_t dim = ca->dim[level];
|
|
727
|
-
ca_size_t shift = ca->shift[level];
|
|
728
|
-
int8_t roll = ca->roll[level];
|
|
729
|
-
ca_size_t i;
|
|
730
|
-
|
|
731
|
-
if ( level == ca->ndim - 1 ) {
|
|
732
|
-
if ( ( ! shift ) || roll ) {
|
|
733
|
-
for (i=0; i<dim; i++) {
|
|
734
|
-
idx0[level] = i;
|
|
735
|
-
memcpy(ca_ptr_at_index(ca->parent, idx0), ptr, ca->bytes);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
else {
|
|
739
|
-
if ( shift > 0 ) {
|
|
740
|
-
shift = ( shift >= dim ) ? dim : shift;
|
|
741
|
-
|
|
742
|
-
for (i=0; i<shift; i++) {
|
|
743
|
-
; /* do nothing */
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
if ( shift < dim ) {
|
|
747
|
-
for (i=0; i<dim-shift; i++) {
|
|
748
|
-
idx0[level] = i;
|
|
749
|
-
memcpy(ca_ptr_at_index(ca->parent, idx0), ptr, ca->bytes);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
else {
|
|
754
|
-
shift = ( -shift >= dim ) ? -dim : shift;
|
|
755
|
-
|
|
756
|
-
if ( -shift < dim ) {
|
|
757
|
-
for (i=0; i<dim+shift; i++) {
|
|
758
|
-
idx0[level] = -shift+i;
|
|
759
|
-
memcpy(ca_ptr_at_index(ca->parent, idx0), ptr, ca->bytes);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
for (i=0; i<-shift; i++) {
|
|
764
|
-
; /* do nothing */
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
else {
|
|
770
|
-
if ( ( ! shift ) || roll ) {
|
|
771
|
-
for (i=0; i<dim; i++) {
|
|
772
|
-
idx0[level] = i;
|
|
773
|
-
ca_shift_fill_loop(ca, ptr, level+1, idx0);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
else {
|
|
777
|
-
if ( shift > 0 ) {
|
|
778
|
-
shift = ( shift >= dim ) ? dim : shift;
|
|
779
|
-
|
|
780
|
-
for (i=0; i<shift; i++) {
|
|
781
|
-
; /* do nothing */
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if ( shift < dim ) {
|
|
785
|
-
for (i=0; i<dim-shift; i++) {
|
|
786
|
-
idx0[level] = i;
|
|
787
|
-
ca_shift_fill_loop(ca, ptr, level+1, idx0);
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
shift = ( -shift >= dim ) ? -dim : shift;
|
|
793
|
-
|
|
794
|
-
if ( -shift < dim ) {
|
|
795
|
-
for (i=0; i<dim+shift; i++) {
|
|
796
|
-
idx0[level] = -shift+i;
|
|
797
|
-
ca_shift_fill_loop(ca, ptr, level+1, idx0);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
for (i=0; i<-shift; i++) {
|
|
802
|
-
; /* do nothing */
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
static void
|
|
810
|
-
ca_shift_fill (CAShift *ca, char *ptr)
|
|
811
|
-
{
|
|
812
|
-
ca_size_t idx0[CA_RANK_MAX];
|
|
813
|
-
ca_shift_fill_loop(ca, ptr, (int16_t) 0, idx0);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
/* ------------------------------------------------------------------- */
|
|
817
|
-
|
|
818
|
-
/*
|
|
819
|
-
static VALUE
|
|
820
|
-
rb_ca_shift_set_fill_value (VALUE self, VALUE rfval)
|
|
821
|
-
{
|
|
822
|
-
CAShift *ca;
|
|
823
|
-
CArray *cs;
|
|
824
|
-
|
|
825
|
-
TypedData_Get_Struct(self, CAShift, &cashift_data_type, ca);
|
|
826
|
-
|
|
827
|
-
if ( NIL_P(rfval) ) {
|
|
828
|
-
memset(ca->fill, 0, ca->bytes);
|
|
829
|
-
}
|
|
830
|
-
else {
|
|
831
|
-
cs = ca_wrap_readonly(rfval, ca->data_type);
|
|
832
|
-
memcpy(ca->fill, cs->ptr, ca->bytes);
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
return rfval;
|
|
836
|
-
}
|
|
837
|
-
*/
|
|
838
|
-
|
|
839
243
|
VALUE
|
|
840
|
-
rb_ca_shift_new (VALUE cary, ca_size_t *shift, char *fill, int8_t *roll
|
|
244
|
+
rb_ca_shift_new (VALUE cary, ca_size_t *shift, char *fill, int8_t *roll,
|
|
245
|
+
int fill_mask)
|
|
841
246
|
{
|
|
842
247
|
volatile VALUE obj;
|
|
843
248
|
CArray *parent;
|
|
844
249
|
CAShift *ca;
|
|
845
250
|
rb_check_carray_object(cary);
|
|
846
251
|
TypedData_Get_Struct(cary, CArray, &carray_data_type, parent);
|
|
847
|
-
ca = ca_shift_new(parent, shift, fill, roll);
|
|
252
|
+
ca = ca_shift_new(parent, shift, fill, roll, fill_mask);
|
|
848
253
|
obj = ca_wrap_struct(ca);
|
|
849
254
|
rb_ca_set_parent(obj, cary);
|
|
850
|
-
rb_ca_data_type_inherit(obj, cary);
|
|
851
255
|
return obj;
|
|
852
256
|
}
|
|
853
257
|
|
|
854
|
-
/*
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
*/
|
|
860
|
-
|
|
258
|
+
/* CArray#shift(*shifts, fill_value:) — returns a CAShift view translated
|
|
259
|
+
* by `shifts` along each axis (one shift per dimension).
|
|
260
|
+
*
|
|
261
|
+
* Out-of-range cells take fill_value (default 0); fill_value: UNDEF masks
|
|
262
|
+
* them instead. Raises ArgumentError on argument-count mismatch, on the
|
|
263
|
+
* removed :roll option, and on the removed block form. */
|
|
861
264
|
VALUE
|
|
862
265
|
rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
863
266
|
{
|
|
@@ -867,6 +270,7 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
867
270
|
ca_size_t shift[CA_RANK_MAX];
|
|
868
271
|
int8_t roll[CA_RANK_MAX];
|
|
869
272
|
char *fill = NULL;
|
|
273
|
+
int fill_mask = 0;
|
|
870
274
|
int8_t i;
|
|
871
275
|
|
|
872
276
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
@@ -874,6 +278,15 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
874
278
|
ropt = rb_pop_options(&argc, &argv);
|
|
875
279
|
rb_scan_options(ropt, "roll,fill_value", &rroll, &rfval);
|
|
876
280
|
|
|
281
|
+
/* The :roll option was removed in 3.0. Cyclic shift is now CArray#roll
|
|
282
|
+
(returns a CARoll view, ca_obj_roll.c). Mixed per-axis roll is
|
|
283
|
+
expressed via chain: a.roll(1, 0) followed by .shift(...). */
|
|
284
|
+
if ( ! NIL_P(rroll) ) {
|
|
285
|
+
rb_raise(rb_eArgError,
|
|
286
|
+
"shift: :roll option removed in 3.0; "
|
|
287
|
+
"use CArray#roll(...) for cyclic shift (returns CARoll view)");
|
|
288
|
+
}
|
|
289
|
+
|
|
877
290
|
if ( argc != ca->ndim ) {
|
|
878
291
|
rb_raise(rb_eArgError, "# of arguments mismatch with ndim");
|
|
879
292
|
}
|
|
@@ -882,16 +295,14 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
882
295
|
shift[i] = NUM2SIZE(argv[i]);
|
|
883
296
|
}
|
|
884
297
|
|
|
885
|
-
if (
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
}
|
|
890
|
-
else {
|
|
891
|
-
/* rb_warn(":fill_value option for CArray#shifted will be obsoleted."); */
|
|
298
|
+
if ( rb_block_given_p() ) {
|
|
299
|
+
rb_raise(rb_eArgError,
|
|
300
|
+
"shift: block form for fill value removed in 3.0; "
|
|
301
|
+
"use fill_value: kwarg (e.g. shift(1, fill_value: -2))");
|
|
892
302
|
}
|
|
893
303
|
|
|
894
304
|
if ( rfval == CA_NIL ) {
|
|
305
|
+
/* Default fill value = 0 (or INT2NUM(0) for OBJECT type) */
|
|
895
306
|
rcs = rb_cscalar_new(ca->data_type, ca->bytes, NULL);
|
|
896
307
|
TypedData_Get_Struct(rcs, CScalar, &cscalar_data_type, cs);
|
|
897
308
|
fill = cs->ptr;
|
|
@@ -900,10 +311,12 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
900
311
|
}
|
|
901
312
|
else {
|
|
902
313
|
memset(fill, 0, cs->bytes);
|
|
903
|
-
}
|
|
314
|
+
}
|
|
904
315
|
}
|
|
905
316
|
else if ( rfval == CA_UNDEF ) {
|
|
317
|
+
/* Range-outside cells should be masked, not value-filled. */
|
|
906
318
|
fill = NULL;
|
|
319
|
+
fill_mask = 1;
|
|
907
320
|
}
|
|
908
321
|
else {
|
|
909
322
|
rcs = rb_cscalar_new_with_value(ca->data_type, ca->bytes, rfval);
|
|
@@ -928,14 +341,9 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
928
341
|
}
|
|
929
342
|
}
|
|
930
343
|
|
|
931
|
-
obj = rb_ca_shift_new(self, shift, fill, roll);
|
|
932
|
-
|
|
933
|
-
if ( rfval == CA_UNDEF ) {
|
|
934
|
-
CArray *co;
|
|
935
|
-
TypedData_Get_Struct(obj, CArray, &carray_data_type, co);
|
|
936
|
-
ca_create_mask(co);
|
|
937
|
-
}
|
|
344
|
+
obj = rb_ca_shift_new(self, shift, fill, roll, fill_mask);
|
|
938
345
|
|
|
346
|
+
CA_FACE_LIFT_IF_FACE(obj, self, ca);
|
|
939
347
|
return obj;
|
|
940
348
|
}
|
|
941
349
|
|
|
@@ -952,31 +360,61 @@ static VALUE
|
|
|
952
360
|
rb_ca_shift_initialize_copy (VALUE self, VALUE other)
|
|
953
361
|
{
|
|
954
362
|
CAShift *ca, *cs;
|
|
363
|
+
ca_size_t shift[CA_RANK_MAX];
|
|
364
|
+
int8_t roll[CA_RANK_MAX];
|
|
365
|
+
int fill_mask = 0;
|
|
366
|
+
int8_t k;
|
|
955
367
|
|
|
956
368
|
TypedData_Get_Struct(self, CAShift, &cashift_data_type, ca);
|
|
957
369
|
TypedData_Get_Struct(other, CAShift, &cashift_data_type, cs);
|
|
958
370
|
|
|
959
|
-
|
|
371
|
+
/* Recover shift/roll/fill_mask from cs (same scheme as clone). */
|
|
372
|
+
for (k = 0; k < cs->ndim; k++) {
|
|
373
|
+
shift[k] = -cs->start[k];
|
|
374
|
+
if ( cs->bounds[k] == CA_BOUNDS_PERIODIC ) {
|
|
375
|
+
roll[k] = 1;
|
|
376
|
+
} else {
|
|
377
|
+
roll[k] = 0;
|
|
378
|
+
if ( cs->bounds[k] == CA_BOUNDS_MASK ) fill_mask = 1;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/* `self` came from rb_ca_shift_s_allocate (TypedData_Make_Struct,
|
|
382
|
+
_pool == NULL). Attach the pool before setup. */
|
|
383
|
+
if ( ca_func[CA_OBJ_SHIFT].pool_init ) {
|
|
384
|
+
ca_array_pool_alloc(ca, CA_OBJ_SHIFT, cs->ndim);
|
|
385
|
+
}
|
|
386
|
+
ca_shift_setup(ca, cs->parent, shift, cs->fill, roll, fill_mask);
|
|
960
387
|
|
|
961
388
|
return self;
|
|
962
389
|
}
|
|
963
390
|
|
|
391
|
+
/* `shift!` removed in 3.0; the canonical in-place idiom is
|
|
392
|
+
`ca[] = ca.shift(...)`.
|
|
393
|
+
[MOVED] roll -> ext/ca_obj_roll.c (CARoll view). */
|
|
394
|
+
|
|
964
395
|
void
|
|
965
|
-
Init_ca_obj_shift ()
|
|
396
|
+
Init_ca_obj_shift (void)
|
|
966
397
|
{
|
|
967
|
-
|
|
398
|
+
/* Build the CAShift op table by copying CAWindow's and overriding
|
|
399
|
+
just the slots that need to produce CAShift-typed results. */
|
|
400
|
+
ca_shift_func = ca_window_func;
|
|
401
|
+
ca_shift_func.free_object = free_ca_shift;
|
|
402
|
+
ca_shift_func.clone = ca_shift_func_clone;
|
|
403
|
+
ca_shift_func.create_mask = ca_shift_func_create_mask;
|
|
404
|
+
|
|
405
|
+
rb_cCAShift = rb_define_class("CAShift", rb_cCAWindow);
|
|
968
406
|
rb_cCAShiftMask = rb_define_class("CAShiftMask", rb_cCAShift);
|
|
969
407
|
|
|
970
|
-
CA_OBJ_SHIFT = ca_install_obj_type(rb_cCAShift,
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
408
|
+
CA_OBJ_SHIFT = ca_install_obj_type(rb_cCAShift,
|
|
409
|
+
&cashift_data_type,
|
|
410
|
+
rb_cCAShiftMask,
|
|
411
|
+
&cashift_mask_data_type, &ca_shift_func, sizeof(ca_shift_func));
|
|
974
412
|
rb_define_const(rb_cObject, "CA_OBJ_SHIFT", INT2NUM(CA_OBJ_SHIFT));
|
|
975
413
|
|
|
976
|
-
rb_define_method(rb_cCArray, "
|
|
414
|
+
rb_define_method(rb_cCArray, "shift", rb_ca_shift, -1);
|
|
415
|
+
/* "shift!" removed in 3.0; "roll" defined in Init_ca_obj_roll. */
|
|
977
416
|
|
|
978
417
|
rb_define_alloc_func(rb_cCAShift, rb_ca_shift_s_allocate);
|
|
979
418
|
rb_define_method(rb_cCAShift, "initialize_copy",
|
|
980
419
|
rb_ca_shift_initialize_copy, 1);
|
|
981
420
|
}
|
|
982
|
-
|