@@ -8949,10 +8949,6 @@ Perl__invlist_union_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
8949
8949
UV i_b = 0;
8950
8950
UV i_u = 0;
8951
8951
8952
- bool has_something_from_a = FALSE;
8953
- bool has_something_from_b = FALSE;
8954
-
8955
-
8956
8952
/* running count, as explained in the algorithm source book; items are
8957
8953
* stopped accumulating and are output when the count changes to/from 0.
8958
8954
* The count is incremented when we start a range that's in the set, and
@@ -9118,12 +9114,10 @@ Perl__invlist_union_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9118
9114
{
9119
9115
cp_in_set = ELEMENT_RANGE_MATCHES_INVLIST(i_a);
9120
9116
cp= array_a[i_a++];
9121
- has_something_from_a = TRUE;
9122
9117
}
9123
9118
else {
9124
9119
cp_in_set = ELEMENT_RANGE_MATCHES_INVLIST(i_b);
9125
9120
cp = array_b[i_b++];
9126
- has_something_from_b = TRUE;
9127
9121
}
9128
9122
9129
9123
/* Here, have chosen which of the two inputs to look at. Only output
@@ -9172,54 +9166,10 @@ Perl__invlist_union_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9172
9166
* be output. (If 'count' is non-zero, then the input list we exhausted
9173
9167
* has everything remaining up to the machine's limit in its set, and hence
9174
9168
* in the union, so there will be no further output. */
9175
- if (count != 0) {
9176
-
9177
- /* Here, there is nothing left to put in the union. If the union came
9178
- * only from the input that it is to overwrite, this whole operation is
9179
- * a no-op */
9180
- if ( UNLIKELY(! has_something_from_b && *output == a)
9181
- || UNLIKELY(! has_something_from_a && *output == b))
9182
- {
9183
- SvREFCNT_dec_NN(u);
9184
- return;
9185
- }
9186
-
9187
- len_u = i_u;
9188
- }
9189
- else {
9190
- /* When 'count' is 0, the list that was exhausted (if one was shorter
9191
- * than the other) ended with everything above it not in its set. That
9192
- * means that the remaining part of the union is precisely the same as
9193
- * the non-exhausted list, so can just copy it unchanged. If only one
9194
- * of the inputs contributes to the union, and the output is to
9195
- * overwite that particular input, then this whole operation was a
9196
- * no-op. */
9197
-
9198
- IV copy_count = len_a - i_a;
9199
- if (copy_count > 0) {
9200
- if (UNLIKELY(! has_something_from_b && *output == a)) {
9201
- SvREFCNT_dec_NN(u);
9202
- return;
9203
- }
9204
- Copy(array_a + i_a, array_u + i_u, copy_count, UV);
9205
- len_u = i_u + copy_count;
9206
- }
9207
- else if ((copy_count = len_b - i_b) > 0) {
9208
- if (UNLIKELY(! has_something_from_a && *output == b)) {
9209
- SvREFCNT_dec_NN(u);
9210
- return;
9211
- }
9212
- Copy(array_b + i_b, array_u + i_u, copy_count, UV);
9213
- len_u = i_u + copy_count;
9214
- } else if ( UNLIKELY(! has_something_from_b && *output == a)
9215
- || UNLIKELY(! has_something_from_a && *output == b))
9216
- {
9217
- /* Here, both arrays are exhausted, so no need to do any additional
9218
- * copying. Also here, the union came only from the input that it is
9219
- * to overwrite, so this whole operation is a no-op */
9220
- SvREFCNT_dec_NN(u);
9221
- return;
9222
- }
9169
+ len_u = i_u;
9170
+ if (count == 0) {
9171
+ /* At most one of the subexpressions will be non-zero */
9172
+ len_u += (len_a - i_a) + (len_b - i_b);
9223
9173
}
9224
9174
9225
9175
/* Set the result to the final length, which can change the pointer to
@@ -9231,6 +9181,22 @@ Perl__invlist_union_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9231
9181
array_u = invlist_array(u);
9232
9182
}
9233
9183
9184
+ /* When 'count' is 0, the list that was exhausted (if one was shorter than
9185
+ * the other) ended with everything above it not in its set. That means
9186
+ * that the remaining part of the union is precisely the same as the
9187
+ * non-exhausted list, so can just copy it unchanged. (If both lists were
9188
+ * exhausted at the same time, then the operations below will be both 0.)
9189
+ */
9190
+ if (count == 0) {
9191
+ IV copy_count; /* At most one will have a non-zero copy count */
9192
+ if ((copy_count = len_a - i_a) > 0) {
9193
+ Copy(array_a + i_a, array_u + i_u, copy_count, UV);
9194
+ }
9195
+ else if ((copy_count = len_b - i_b) > 0) {
9196
+ Copy(array_b + i_b, array_u + i_u, copy_count, UV);
9197
+ }
9198
+ }
9199
+
9234
9200
/* If the output is not to overwrite either of the inputs, just return the
9235
9201
* calculated union */
9236
9202
if (a != *output && b != *output) {
@@ -9303,9 +9269,6 @@ Perl__invlist_intersection_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9303
9269
*/
9304
9270
UV count = 0;
9305
9271
9306
- bool has_something_from_a = FALSE;
9307
- bool has_something_from_b = FALSE;
9308
-
9309
9272
PERL_ARGS_ASSERT__INVLIST_INTERSECTION_MAYBE_COMPLEMENT_2ND;
9310
9273
assert(a != b);
9311
9274
@@ -9402,12 +9365,10 @@ Perl__invlist_intersection_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9402
9365
{
9403
9366
cp_in_set = ELEMENT_RANGE_MATCHES_INVLIST(i_a);
9404
9367
cp= array_a[i_a++];
9405
- has_something_from_a = TRUE;
9406
9368
}
9407
9369
else {
9408
9370
cp_in_set = ELEMENT_RANGE_MATCHES_INVLIST(i_b);
9409
9371
cp= array_b[i_b++];
9410
- has_something_from_b = TRUE;
9411
9372
}
9412
9373
9413
9374
/* Here, have chosen which of the two inputs to look at. Only output
@@ -9449,52 +9410,12 @@ Perl__invlist_intersection_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9449
9410
count++;
9450
9411
}
9451
9412
9452
- if (count < 2) {
9453
-
9454
- /* Here, there is nothing left to put in the intersection. If the
9455
- * intersection came only from the input that it is to overwrite, this
9456
- * whole operation is a no-op */
9457
- if ( UNLIKELY(! has_something_from_b && *i == a)
9458
- || UNLIKELY(! has_something_from_a && *i == b))
9459
- {
9460
- SvREFCNT_dec_NN(r);
9461
- return;
9462
- }
9463
-
9464
- len_r = i_r;
9465
- }
9466
- else {
9467
- /* When 'count' is 2 or more, the list that was exhausted, what remains
9468
- * in the intersection is precisely the same as the non-exhausted list,
9469
- * so can just copy it unchanged. If only one of the inputs
9470
- * contributes to the intersection, and the output is to overwite that
9471
- * particular input, then this whole operation was a no-op. */
9472
-
9473
- IV copy_count = len_a - i_a;
9474
- if (copy_count > 0) {
9475
- if (UNLIKELY(! has_something_from_b && *i == a)) {
9476
- SvREFCNT_dec_NN(r);
9477
- return;
9478
- }
9479
- Copy(array_a + i_a, array_r + i_r, copy_count, UV);
9480
- len_r = i_r + copy_count;
9481
- }
9482
- else if ((copy_count = len_b - i_b) > 0) {
9483
- if (UNLIKELY(! has_something_from_a && *i == b)) {
9484
- SvREFCNT_dec_NN(r);
9485
- return;
9486
- }
9487
- Copy(array_b + i_b, array_r + i_r, copy_count, UV);
9488
- len_r = i_r + copy_count;
9489
- } else if ( UNLIKELY(! has_something_from_b && *i == a)
9490
- || UNLIKELY(! has_something_from_a && *i == b))
9491
- {
9492
- /* Here, both arrays are exhausted, so no need to do any additional
9493
- * copying. Also here, the intersection came only from the input
9494
- * that it is to overwrite, so this whole operation is a no-op */
9495
- SvREFCNT_dec_NN(r);
9496
- return;
9497
- }
9413
+ /* The final length is what we've output so far plus what else is in the
9414
+ * intersection. At most one of the subexpressions below will be non-zero
9415
+ * */
9416
+ len_r = i_r;
9417
+ if (count >= 2) {
9418
+ len_r += (len_a - i_a) + (len_b - i_b);
9498
9419
}
9499
9420
9500
9421
/* Set the result to the final length, which can change the pointer to
@@ -9506,6 +9427,17 @@ Perl__invlist_intersection_maybe_complement_2nd(pTHX_ SV* const a, SV* const b,
9506
9427
array_r = invlist_array(r);
9507
9428
}
9508
9429
9430
+ /* Finish outputting any remaining */
9431
+ if (count >= 2) { /* At most one will have a non-zero copy count */
9432
+ IV copy_count;
9433
+ if ((copy_count = len_a - i_a) > 0) {
9434
+ Copy(array_a + i_a, array_r + i_r, copy_count, UV);
9435
+ }
9436
+ else if ((copy_count = len_b - i_b) > 0) {
9437
+ Copy(array_b + i_b, array_r + i_r, copy_count, UV);
9438
+ }
9439
+ }
9440
+
9509
9441
/* If the output is not to overwrite either of the inputs, just return the
9510
9442
* calculated intersection */
9511
9443
if (a != *i && b != *i) {
0 commit comments