@@ -441,11 +441,36 @@ ALGDEF T *NS(partition)(
441
441
void * predicate_ctx
442
442
);
443
443
444
- ALGDEF T * NS (partition_copy )(
444
+ /// Partition a range by copying the elements that satisfy a predicate into one buffer,
445
+ /// and the ones that fail to another.
446
+ /// Note that this function is stable.
447
+ ALGDEF void NS (partition_copy )(
445
448
const T * first ,
446
449
const T * last ,
447
- T * restrict out_false ,
448
- T * restrict out_true ,
450
+ T * * out_true ,
451
+ T * * out_false ,
452
+ int (* predicate )(const T * , void * ),
453
+ void * predicate_ctx
454
+ );
455
+
456
+ /// Calls malloc.
457
+ ALGDEF T * NS (stable_partition )(
458
+ T * first ,
459
+ T * last ,
460
+ int (* predicate )(const T * , void * ),
461
+ void * predicate_ctx
462
+ );
463
+
464
+ /// Like above, but does not call `malloc`.
465
+ /// You must provide a buffer.
466
+ /// requires:
467
+ /// - sizeof(buffer) >= the number of false entries in the range [first, last)
468
+ // Note that sizeof(buffer) >= last - first will be sufficient.
469
+
470
+ ALGDEF T * NS (stable_partition_with_buffer )(
471
+ T * first ,
472
+ T * last ,
473
+ T * buffer ,
449
474
int (* predicate )(const T * , void * ),
450
475
void * predicate_ctx
451
476
);
@@ -644,17 +669,16 @@ ALGDEF void NS(insertion_sort_stable)(
644
669
645
670
/// Sort an array in a stable way with a merge sort variety.
646
671
/// By stable, we mean that the order of equivalent elements is preserved.
647
- /// Note this function allocates memory with malloc.
648
-
672
+ /// Calls malloc.
649
673
ALGDEF void NS (stable_sort )(
650
674
T * first ,
651
675
T * last ,
652
676
int (* compare )(const T * , const T * , void * ),
653
677
void * compare_ctx
654
678
);
655
679
656
- /// Like above, but does not call ` malloc` .
657
- /// You provide a buffer.`
680
+ /// Like above, but does not call malloc.
681
+ /// You must provide a buffer.
658
682
/// requires:
659
683
/// - sizeof(buffer) >= (last - first) / 2
660
684
ALGDEF void NS (stable_sort_with_buffer )(
@@ -766,6 +790,7 @@ ALGDEF T *NS(_merge_sort_adaptive_with_buffer_n)(
766
790
void * compare_ctx
767
791
);
768
792
793
+
769
794
#ifdef ARRAY_ALG_IMPLEMENTATION
770
795
771
796
ALGDEF T * NS (find_if )(
@@ -1515,11 +1540,41 @@ ALGDEF T *NS(partition)(
1515
1540
return out ;
1516
1541
}
1517
1542
1518
- ALGDEF T * NS (partition_copy )(
1543
+ ALGDEF T * NS (stable_partition_with_buffer )(
1544
+ T * first ,
1545
+ T * last ,
1546
+ T * buffer ,
1547
+ int (* predicate )(const T * , void * ),
1548
+ void * predicate_ctx
1549
+ )
1550
+ {
1551
+ T * out_false = buffer ;
1552
+ T * out_true = first ;
1553
+ NS (partition_copy )(first , last , & out_true , & out_false , predicate , predicate_ctx );
1554
+ memcpy (out_true , buffer , sizeof (T ) * (out_false - buffer ));
1555
+ return out_true ;
1556
+ }
1557
+
1558
+ ALGDEF T * NS (stable_partition )(
1559
+ T * first ,
1560
+ T * last ,
1561
+ int (* predicate )(const T * , void * ),
1562
+ void * predicate_ctx
1563
+ )
1564
+ {
1565
+ // TODO: this is not the best implementation
1566
+ if (first == last ) return last ;
1567
+ T * buffer = malloc ((last - first ) * sizeof (T ));
1568
+ T * point = NS (stable_partition_with_buffer )(first , last , buffer , predicate , predicate_ctx );
1569
+ free (buffer );
1570
+ return point ;
1571
+ }
1572
+
1573
+ ALGDEF void NS (partition_copy )(
1519
1574
const T * first ,
1520
1575
const T * last ,
1521
- T * restrict out_false ,
1522
- T * restrict out_true ,
1576
+ T * * out_true ,
1577
+ T * * out_false ,
1523
1578
int (* predicate )(const T * , void * ),
1524
1579
void * predicate_ctx
1525
1580
) {
@@ -1528,19 +1583,19 @@ ALGDEF T *NS(partition_copy)(
1528
1583
{
1529
1584
if (predicate (first , predicate_ctx ))
1530
1585
{
1531
- * out_true = * first ;
1532
- ++ out_true ;
1586
+ * ( * out_true ) = * first ;
1587
+ ++ ( * out_true ) ;
1533
1588
}
1534
1589
else
1535
1590
{
1536
- * out_false = * first ;
1537
- ++ out_false ;
1591
+ * ( * out_false ) = * first ;
1592
+ ++ ( * out_false ) ;
1538
1593
}
1539
1594
++ first ;
1540
1595
}
1541
- return out_false ;
1542
1596
}
1543
1597
1598
+
1544
1599
ALGDEF T * NS (partition_point_n )(
1545
1600
const T * first ,
1546
1601
size_t n ,
0 commit comments