@@ -450,6 +450,63 @@ string_lrstrip_chars_loop(PyArrayMethod_Context *context,
450
450
}
451
451
452
452
453
+ template <ENCODING enc>
454
+ static int
455
+ string_expandtabs_length_loop (PyArrayMethod_Context *context,
456
+ char *const data[], npy_intp const dimensions[],
457
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED (auxdata))
458
+ {
459
+ int elsize = context->descriptors [0 ]->elsize ;
460
+
461
+ char *in1 = data[0 ];
462
+ char *in2 = data[1 ];
463
+ char *out = data[2 ];
464
+
465
+ npy_intp N = dimensions[0 ];
466
+
467
+ while (N--) {
468
+ Buffer<enc> buf (in1, elsize);
469
+ *(npy_intp *)out = string_expandtabs_length (buf, *(npy_int64 *)in2);
470
+
471
+ in1 += strides[0 ];
472
+ in2 += strides[1 ];
473
+ out += strides[2 ];
474
+ }
475
+
476
+ return 0 ;
477
+ }
478
+
479
+
480
+ template <ENCODING enc>
481
+ static int
482
+ string_expandtabs_loop (PyArrayMethod_Context *context,
483
+ char *const data[], npy_intp const dimensions[],
484
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED (auxdata))
485
+ {
486
+ int elsize = context->descriptors [0 ]->elsize ;
487
+ int outsize = context->descriptors [2 ]->elsize ;
488
+
489
+ char *in1 = data[0 ];
490
+ char *in2 = data[1 ];
491
+ char *out = data[2 ];
492
+
493
+ npy_intp N = dimensions[0 ];
494
+
495
+ while (N--) {
496
+ Buffer<enc> buf (in1, elsize);
497
+ Buffer<enc> outbuf (out, outsize);
498
+ npy_intp new_len = string_expandtabs (buf, *(npy_int64 *)in2, outbuf);
499
+ outbuf.buffer_fill_with_zeros_after_index (new_len);
500
+
501
+ in1 += strides[0 ];
502
+ in2 += strides[1 ];
503
+ out += strides[2 ];
504
+ }
505
+
506
+ return 0 ;
507
+ }
508
+
509
+
453
510
/* Resolve descriptors & promoter functions */
454
511
455
512
static NPY_CASTING
@@ -517,9 +574,9 @@ string_multiply_resolve_descriptors(
517
574
static NPY_CASTING
518
575
string_strip_whitespace_resolve_descriptors (
519
576
PyArrayMethodObject *NPY_UNUSED (self),
520
- PyArray_DTypeMeta *NPY_UNUSED(dtypes[3 ]),
521
- PyArray_Descr *given_descrs[3 ],
522
- PyArray_Descr *loop_descrs[3 ],
577
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[2 ]),
578
+ PyArray_Descr *given_descrs[2 ],
579
+ PyArray_Descr *loop_descrs[2 ],
523
580
npy_intp *NPY_UNUSED(view_offset))
524
581
{
525
582
loop_descrs[0 ] = NPY_DT_CALL_ensure_canonical (given_descrs[0 ]);
@@ -600,7 +657,7 @@ string_replace_promoter(PyObject *NPY_UNUSED(ufunc),
600
657
static NPY_CASTING
601
658
string_replace_resolve_descriptors (
602
659
PyArrayMethodObject *NPY_UNUSED (self),
603
- PyArray_DTypeMeta *NPY_UNUSED(dtypes[3 ]),
660
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[5 ]),
604
661
PyArray_Descr *given_descrs[5],
605
662
PyArray_Descr *loop_descrs[5],
606
663
npy_intp *NPY_UNUSED(view_offset))
@@ -651,6 +708,67 @@ string_startswith_endswith_promoter(PyObject *NPY_UNUSED(ufunc),
651
708
}
652
709
653
710
711
+ static int
712
+ string_expandtabs_length_promoter (PyObject *NPY_UNUSED (ufunc),
713
+ PyArray_DTypeMeta *op_dtypes[], PyArray_DTypeMeta *signature[],
714
+ PyArray_DTypeMeta *new_op_dtypes[])
715
+ {
716
+ Py_INCREF (op_dtypes[0 ]);
717
+ new_op_dtypes[0 ] = op_dtypes[0 ];
718
+ new_op_dtypes[1 ] = NPY_DT_NewRef (&PyArray_Int64DType);
719
+ new_op_dtypes[2 ] = PyArray_DTypeFromTypeNum (NPY_DEFAULT_INT);
720
+ return 0 ;
721
+ }
722
+
723
+
724
+ static int
725
+ string_expandtabs_promoter (PyObject *NPY_UNUSED (ufunc),
726
+ PyArray_DTypeMeta *op_dtypes[], PyArray_DTypeMeta *signature[],
727
+ PyArray_DTypeMeta *new_op_dtypes[])
728
+ {
729
+ Py_INCREF (op_dtypes[0 ]);
730
+ new_op_dtypes[0 ] = op_dtypes[0 ];
731
+ new_op_dtypes[1 ] = NPY_DT_NewRef (&PyArray_Int64DType);
732
+ Py_INCREF (op_dtypes[0 ]);
733
+ new_op_dtypes[2 ] = op_dtypes[0 ];
734
+ return 0 ;
735
+ }
736
+
737
+
738
+ static NPY_CASTING
739
+ string_expandtabs_resolve_descriptors (
740
+ PyArrayMethodObject *NPY_UNUSED (self),
741
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[3 ]),
742
+ PyArray_Descr *given_descrs[3],
743
+ PyArray_Descr *loop_descrs[3],
744
+ npy_intp *NPY_UNUSED(view_offset))
745
+ {
746
+ if (given_descrs[2 ] == NULL ) {
747
+ PyErr_SetString (
748
+ PyExc_TypeError,
749
+ " The 'out' kwarg is necessary. Use numpy.strings.expandtabs without it." );
750
+ return _NPY_ERROR_OCCURRED_IN_CAST;
751
+ }
752
+
753
+ loop_descrs[0 ] = NPY_DT_CALL_ensure_canonical (given_descrs[0 ]);
754
+ if (loop_descrs[0 ] == NULL ) {
755
+ return _NPY_ERROR_OCCURRED_IN_CAST;
756
+ }
757
+
758
+ loop_descrs[1 ] = NPY_DT_CALL_ensure_canonical (given_descrs[1 ]);
759
+ if (loop_descrs[1 ] == NULL ) {
760
+ return _NPY_ERROR_OCCURRED_IN_CAST;
761
+ }
762
+
763
+ loop_descrs[2 ] = NPY_DT_CALL_ensure_canonical (given_descrs[2 ]);
764
+ if (loop_descrs[2 ] == NULL ) {
765
+ return _NPY_ERROR_OCCURRED_IN_CAST;
766
+ }
767
+
768
+ return NPY_NO_CASTING;
769
+ }
770
+
771
+
654
772
/*
655
773
* Machinery to add the string loops to the existing ufuncs.
656
774
*/
@@ -1130,6 +1248,42 @@ init_string_ufuncs(PyObject *umath)
1130
1248
}
1131
1249
}
1132
1250
1251
+ dtypes[0 ] = NPY_OBJECT;
1252
+ dtypes[1 ] = NPY_INT64;
1253
+ dtypes[2 ] = NPY_DEFAULT_INT;
1254
+ if (init_ufunc (
1255
+ umath, " _expandtabs_length" , 2 , 1 , dtypes, ENCODING::ASCII,
1256
+ string_expandtabs_length_loop<ENCODING::ASCII>, NULL , NULL ) < 0 ) {
1257
+ return -1 ;
1258
+ }
1259
+ if (init_ufunc (
1260
+ umath, " _expandtabs_length" , 2 , 1 , dtypes, ENCODING::UTF32,
1261
+ string_expandtabs_length_loop<ENCODING::UTF32>, NULL , NULL ) < 0 ) {
1262
+ return -1 ;
1263
+ }
1264
+ if (init_promoter (umath, " _expandtabs_length" , 2 , 1 , string_expandtabs_length_promoter) < 0 ) {
1265
+ return -1 ;
1266
+ }
1267
+
1268
+ dtypes[0 ] = NPY_OBJECT;
1269
+ dtypes[1 ] = NPY_INT64;
1270
+ dtypes[2 ] = NPY_OBJECT;
1271
+ if (init_ufunc (
1272
+ umath, " _expandtabs" , 2 , 1 , dtypes, ENCODING::ASCII,
1273
+ string_expandtabs_loop<ENCODING::ASCII>,
1274
+ string_expandtabs_resolve_descriptors, NULL ) < 0 ) {
1275
+ return -1 ;
1276
+ }
1277
+ if (init_ufunc (
1278
+ umath, " _expandtabs" , 2 , 1 , dtypes, ENCODING::UTF32,
1279
+ string_expandtabs_loop<ENCODING::UTF32>,
1280
+ string_expandtabs_resolve_descriptors, NULL ) < 0 ) {
1281
+ return -1 ;
1282
+ }
1283
+ if (init_promoter (umath, " _expandtabs" , 2 , 1 , string_expandtabs_promoter) < 0 ) {
1284
+ return -1 ;
1285
+ }
1286
+
1133
1287
return 0 ;
1134
1288
}
1135
1289
0 commit comments