-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_6_traits.d
69 lines (64 loc) · 1.95 KB
/
_6_traits.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
unittest
{
import std.functional : binaryFun;
import std.range.primitives : empty, front,
popFront,
isInputRange,
isForwardRange,
isRandomAccessRange,
hasSlicing,
hasLength;
import std.stdio : writeln;
import std.traits : isNarrowString;
/**
Returns the common prefix of two ranges
without the auto-decoding special case.
Params:
pred = Predicate for commonality comparison
r1 = A forward range of elements.
r2 = An input range of elements.
Returns:
A slice of r1 which contains the characters
that both ranges start with.
*/
auto commonPrefix(alias pred = "a == b", R1, R2)
(R1 r1, R2 r2)
if (isForwardRange!R1 && isInputRange!R2 &&
!isNarrowString!R1 &&
is(typeof(binaryFun!pred(r1.front,
r2.front))))
{
import std.algorithm.comparison : min;
static if (isRandomAccessRange!R1 &&
isRandomAccessRange!R2 &&
hasLength!R1 && hasLength!R2 &&
hasSlicing!R1)
{
immutable limit = min(r1.length,
r2.length);
foreach (i; 0 .. limit)
{
if (!binaryFun!pred(r1[i], r2[i]))
{
return r1[0 .. i];
}
}
return r1[0 .. limit];
}
else
{
import std.range : takeExactly;
auto result = r1.save;
size_t i = 0;
for (;
!r1.empty && !r2.empty &&
binaryFun!pred(r1.front, r2.front);
++i, r1.popFront(), r2.popFront())
{}
return takeExactly(result, i);
}
}
assert(commonPrefix("The end of the world"d,
"The end ought to be close"d) == "The end o");
writeln("Test #6 passed");
}