@@ -22,46 +22,29 @@ With either function, the predicate must be a strict ordering just like with
22
22
incorrect and will cause failed assertions.
23
23
24
24
Params:
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.
26
29
+/
27
- template isSorted (alias less = " a < b " )
30
+ template isSorted (alias less = " !(a >= b) " )
28
31
{
29
32
import mir.functional: naryFun;
30
33
static if (__traits(isSame, naryFun! less, less))
31
34
/+ +
32
35
slice = A slice to check for sortedness.
33
36
Returns:
34
- `true` if the range is sorted, false otherwise. `isSorted` allows
37
+ `true` if the ndslice is sorted, false otherwise. `isSorted` allows
35
38
duplicates, $(LREF _isStrictlyMonotonic) not.
36
39
+/
37
40
@fastmath bool isSorted(SliceKind kind, size_t [] packs, Iterator)
38
41
(Slice! (kind, packs, Iterator) slice)
39
42
if (packs.length == 1 )
40
43
{
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" ;
65
48
}
66
49
else
67
50
alias isSorted = .isSorted! (naryFun! less);
@@ -77,16 +60,55 @@ template isStrictlyMonotonic(alias less = "a < b")
77
60
(Slice! (kind, packs, Iterator) slice)
78
61
if (packs.length == 1 )
79
62
{
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" ;
85
66
}
86
67
else
87
68
alias isStrictlyMonotonic = .isStrictlyMonotonic! (naryFun! less);
88
69
}
89
70
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
+
90
112
// /
91
113
template sort (alias less = " a < b" )
92
114
{
0 commit comments