@@ -22,46 +22,29 @@ With either function, the predicate must be a strict ordering just like with
2222incorrect and will cause failed assertions.
2323
2424Params:
25- less = Predicate the range should be sorted by.
25+ less = Predicate the ndslice should be sorted by.
26+ Note:
27+ isSorted requires predicates for floating point types looks like `!(cmp_condition)`
28+ to return false if the ndslice contains NaNs.
2629+/
27- template isSorted (alias less = " a < b " )
30+ template isSorted (alias less = " !(a >= b) " )
2831{
2932 import mir.functional: naryFun;
3033 static if (__traits(isSame, naryFun! less, less))
3134 /+ +
3235 slice = A slice to check for sortedness.
3336 Returns:
34- `true` if the range is sorted, false otherwise. `isSorted` allows
37+ `true` if the ndslice is sorted, false otherwise. `isSorted` allows
3538 duplicates, $(LREF _isStrictlyMonotonic) not.
3639 +/
3740 @fastmath bool isSorted(SliceKind kind, size_t [] packs, Iterator)
3841 (Slice! (kind, packs, Iterator) slice)
3942 if (packs.length == 1 )
4043 {
41- if (slice.anyEmpty)
42- return true ;
43-
44- auto ahead = slice;
45- ahead.popFront();
46-
47- static if (packs[0 ] == 1 )
48- {
49- for (; ! ahead.empty; ahead.popFront(), slice.popFront())
50- {
51- if (! less(ahead.front, slice.front)) continue ;
52- // Check for antisymmetric predicate
53- assert (
54- ! less(slice.front, ahead.front),
55- " Predicate for isSorted is not antisymmetric. Both" ~
56- " pred(a, b) and pred(b, a) are true for certain values." );
57- return false ;
58- }
59- return true ;
60- }
61- else
62- {
63- static assert (" isSorted does not implemented for multidimensional slices." );
64- }
44+ import mir.functional: reverseArgs;
45+ import mir.ndslice.algorithm: all;
46+ import mir.ndslice.topology: flattened, slide;
47+ return slice.flattened.slide! (2 , reverseArgs! less).all! " !a" ;
6548 }
6649 else
6750 alias isSorted = .isSorted! (naryFun! less);
@@ -77,16 +60,55 @@ template isStrictlyMonotonic(alias less = "a < b")
7760 (Slice! (kind, packs, Iterator) slice)
7861 if (packs.length == 1 )
7962 {
80- static if (__traits(isSame, less, less))
81- // /
82- import std.algorithm.searching : findAdjacent;
83- import mir.functional: not;
84- return findAdjacent! (not! less)(r).empty;
63+ import mir.ndslice.algorithm: all;
64+ import mir.ndslice.topology: flattened, slide;
65+ return slice.flattened.slide! (2 , less).all! " a" ;
8566 }
8667 else
8768 alias isStrictlyMonotonic = .isStrictlyMonotonic! (naryFun! less);
8869}
8970
71+
72+ // /
73+ unittest
74+ {
75+ assert ([1 , 1 , 2 ].sliced.isSorted);
76+ // strictly monotonic doesn't allow duplicates
77+ assert (! [1 , 1 , 2 ].sliced.isStrictlyMonotonic);
78+
79+ auto arr = [4 , 3 , 2 , 1 ].sliced;
80+ assert (! isSorted(arr));
81+ assert (! isStrictlyMonotonic(arr));
82+
83+ sort(arr);
84+ assert (isSorted(arr));
85+ assert (isStrictlyMonotonic(arr));
86+ }
87+
88+ unittest
89+ {
90+ auto a = [1 , 2 , 3 ].sliced;
91+ assert (isSorted(a[0 .. 0 ]));
92+ assert (isSorted(a[0 .. 1 ]));
93+ assert (isSorted(a));
94+ auto b = [1 , 3 , 2 ].sliced;
95+ assert (! isSorted(b));
96+
97+ // ignores duplicates
98+ auto c = [1 , 1 , 2 ].sliced;
99+ assert (isSorted(c));
100+ }
101+
102+ unittest
103+ {
104+ assert ([1 , 2 , 3 ][0 .. 0 ].sliced.isStrictlyMonotonic);
105+ assert ([1 , 2 , 3 ][0 .. 1 ].sliced.isStrictlyMonotonic);
106+ assert ([1 , 2 , 3 ].sliced.isStrictlyMonotonic);
107+ assert (! [1 , 3 , 2 ].sliced.isStrictlyMonotonic);
108+ assert (! [1 , 1 , 2 ].sliced.isStrictlyMonotonic);
109+ }
110+
111+
90112// /
91113template sort (alias less = " a < b" )
92114{
0 commit comments