Skip to content

Commit cca8894

Browse files
andralexRazvanN7
authored andcommitted
Added changelog entries for min/maxIndex functions
2 parents 3f8298e + 074da81 commit cca8894

File tree

2 files changed

+119
-21
lines changed

2 files changed

+119
-21
lines changed

changelog.dd

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ $(BUGSTITLE Library Changes,
88
$(LI $(RELATIVE_LINK2 promoted, Added `std.traits.Promoted` to get the result of
99
$(LINK2 $(ROOT_DIR)spec/type.html#integer-promotions, scalar type promotion)
1010
in multi-term arithmetic expressions.))
11+
$(LI $(RELATIVE_LINK2 staticIsSorted, Added `std.meta.staticIsSorted` to check if
12+
an `AliasSeq` is sorted according to some template predicate.))
13+
$(LI $(RELATIVE_LINK2 minIndex, Added `std.algorithm.searching.minIndex`
14+
to get the index of the minimum element of a range.))
15+
$(LI $(RELATIVE_LINK2 maxIndex, Added `std.algorithm.searching.maxIndex`
16+
to get the index of the maximum element of a range.))
17+
1118
)
1219

1320
$(BUGSTITLE Library Changes,
1421

1522
$(LI $(LNAME2 promoted, `std.traits.Promoted` gets the type to which a scalar type will
16-
be promoted in multi-term arithmetic expressions)
23+
be promoted in multi-term arithmetic expressions.)
1724
-------
1825
import std.traits : Promoted;
1926
static assert(is(typeof(ubyte(3) * ubyte(5)) == Promoted!ubyte));
@@ -23,6 +30,47 @@ static assert(is(Promoted!ubyte == int));
2330
scalar type promotions) for more information.)
2431
)
2532

33+
$(LI $(LNAME2 staticIsSorted, `std.meta.staticIsSorted` checks whether an `AliasSeq` is
34+
sorted according to some template predicate.)
35+
------
36+
enum Comp(T1, T2) = T1.sizeof < T2.sizeof;
37+
38+
import std.meta : staticIsSorted;
39+
static assert( staticIsSorted!(Comp, byte, uint, double));
40+
static assert(!staticIsSorted!(Comp, bool, long, dchar));
41+
------
42+
$(P Additionally, the compile-time performance of `std.meta.staticSort` has been
43+
greatly improved. Nevertheless, due to compiler limitations it is still an
44+
extraordinarily expensive operation to perform on longer sequences; strive to
45+
minimize such use.)
46+
)
47+
48+
$(LI $(LNAME2 minIndex, `std.algorithm.searching.minIndex` gets the index of
49+
the minimum element of a range, according to a specified predicate. The
50+
default predicate is "a < b")
51+
-------
52+
import std.algorithm.searching : minIndex;
53+
int[] a = [5, 4, 2, 1, 9, 10];
54+
assert(a.minIndex == 3);
55+
56+
int[] a;
57+
assert(a.minIndex == -1);
58+
-------
59+
)
60+
61+
$(LI $(LNAME2 maxIndex, `std.algorithm.searching.maxIndex` gets the index of
62+
the maximum element of a range, according to a specified predicate. The
63+
default predicate is "a > b")
64+
-------
65+
import std.algorithm.searching : maxIndex;
66+
int[] a = [5, 4, 2, 1, 9, 10];
67+
assert(a.minIndex == 5);
68+
69+
int[] a;
70+
assert(a.minIndex == -1);
71+
-------
72+
)
73+
2674
)
2775

2876
Macros:

std/meta.d

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@
4444
* $(LREF anySatisfy)
4545
* $(LREF staticIndexOf)
4646
* ))
47-
* $(TR $(TD Boolean template predicate operators) $(TD
47+
* $(TR $(TD Template predicates) $(TD
4848
* $(LREF templateAnd)
4949
* $(LREF templateNot)
5050
* $(LREF templateOr)
51+
* $(LREF staticIsSorted)
5152
* ))
5253
* $(TR $(TD Template instantiation) $(TD
5354
* $(LREF ApplyLeft)
@@ -1393,9 +1394,15 @@ template staticSort(alias cmp, Seq...)
13931394
}
13941395
else
13951396
{
1396-
private alias bottom = staticSort!(cmp, Seq[0 .. $ / 2]);
1397+
private alias btm = staticSort!(cmp, Seq[0 .. $ / 2]);
13971398
private alias top = staticSort!(cmp, Seq[$ / 2 .. $]);
1398-
alias staticSort = staticMerge!(cmp, Seq.length / 2, bottom, top);
1399+
1400+
static if (isLessEq!(cmp, btm[$ - 1], top[0]))
1401+
alias staticSort = AliasSeq!(btm, top); // already ascending
1402+
else static if (isLessEq!(cmp, top[$ - 1], btm[0]))
1403+
alias staticSort = AliasSeq!(top, btm); // already descending
1404+
else
1405+
alias staticSort = staticMerge!(cmp, Seq.length / 2, btm, top);
13991406
}
14001407
}
14011408

@@ -1424,31 +1431,74 @@ private template staticMerge(alias cmp, int half, Seq...)
14241431
}
14251432
else
14261433
{
1427-
private enum Result = cmp!(Seq[0], Seq[half]);
1428-
static if (is(typeof(Result) == bool))
1429-
{
1430-
private enum Check = Result;
1431-
}
1432-
else static if (is(typeof(Result) : int))
1433-
{
1434-
private enum Check = Result <= 0;
1435-
}
1436-
else
1434+
static if (isLessEq!(cmp, Seq[0], Seq[half]))
14371435
{
1438-
static assert(0, typeof(Result).stringof ~ " is not a value comparison type");
1439-
}
1440-
static if (Check)
1441-
{
1442-
alias staticMerge = AliasSeq!(Seq[0], staticMerge!(cmp, half - 1, Seq[1 .. $]));
1436+
alias staticMerge = AliasSeq!(Seq[0],
1437+
staticMerge!(cmp, half - 1, Seq[1 .. $]));
14431438
}
14441439
else
14451440
{
1446-
alias staticMerge = AliasSeq!(Seq[half], staticMerge!(cmp, half,
1447-
Seq[0 .. half], Seq[half + 1 .. $]));
1441+
alias staticMerge = AliasSeq!(Seq[half],
1442+
staticMerge!(cmp, half, Seq[0 .. half], Seq[half + 1 .. $]));
14481443
}
14491444
}
14501445
}
14511446

1447+
private template isLessEq(alias cmp, Seq...)
1448+
if (Seq.length == 2)
1449+
{
1450+
private enum Result = cmp!(Seq[1], Seq[0]);
1451+
static if (is(typeof(Result) == bool))
1452+
enum isLessEq = !Result;
1453+
else static if (is(typeof(Result) : int))
1454+
enum isLessEq = Result >= 0;
1455+
else
1456+
static assert(0, typeof(Result).stringof ~ " is not a value comparison type");
1457+
}
1458+
1459+
/**
1460+
* Checks if an $(LREF AliasSeq) is sorted according to $(D cmp).
1461+
*
1462+
* Parameters:
1463+
* cmp = A template that returns a $(D bool) (if its first argument is less than the second one)
1464+
* or an $(D int) (-1 means less than, 0 means equal, 1 means greater than)
1465+
*
1466+
* Seq = The $(LREF AliasSeq) to check
1467+
*
1468+
* Returns: `true` if `Seq` is sorted; otherwise `false`
1469+
*/
1470+
template staticIsSorted(alias cmp, Seq...)
1471+
{
1472+
static if (Seq.length <= 1)
1473+
enum staticIsSorted = true;
1474+
else static if (Seq.length == 2)
1475+
enum staticIsSorted = isLessEq!(cmp, Seq[0], Seq[1]);
1476+
else
1477+
{
1478+
enum staticIsSorted =
1479+
isLessEq!(cmp, Seq[($ / 2) - 1], Seq[$ / 2]) &&
1480+
staticIsSorted!(cmp, Seq[0 .. $ / 2]) &&
1481+
staticIsSorted!(cmp, Seq[$ / 2 .. $]);
1482+
}
1483+
}
1484+
1485+
///
1486+
unittest
1487+
{
1488+
enum Comp(int N1, int N2) = N1 < N2;
1489+
static assert( staticIsSorted!(Comp, 2, 2));
1490+
static assert( staticIsSorted!(Comp, 2, 3, 7, 23));
1491+
static assert(!staticIsSorted!(Comp, 7, 2, 3, 23));
1492+
}
1493+
1494+
///
1495+
unittest
1496+
{
1497+
enum Comp(T1, T2) = __traits(isUnsigned, T2) - __traits(isUnsigned, T1);
1498+
static assert( staticIsSorted!(Comp, uint, ubyte, ulong, short, long));
1499+
static assert(!staticIsSorted!(Comp, uint, short, ubyte, long, ulong));
1500+
}
1501+
14521502
// : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : //
14531503
private:
14541504

0 commit comments

Comments
 (0)