Address review

This commit is contained in:
Sebastian Wilzbach 2018-01-17 04:38:06 +01:00
parent 41d158f4c7
commit 33cf85fdb4
2 changed files with 54 additions and 50 deletions

View file

@ -4722,7 +4722,27 @@ if (substs.length >= 2 && isExpressions!substs)
Complexity: $(BIGOH 1) due to D's $(D switch) guaranteeing $(BIGOH 1); Complexity: $(BIGOH 1) due to D's $(D switch) guaranteeing $(BIGOH 1);
*/ */
auto substitute(Value)(Value value) auto substitute(Value)(Value value)
if (!isInputRange!Value && !is(CommonType!(Value, typeof(substs[0])) == void)) if (isInputRange!Value || !is(CommonType!(Value, typeof(substs[0])) == void))
{
static if (isInputRange!Value)
{
static if (!is(CommonType!(ElementType!Value, typeof(substs[0])) == void))
{
// Substitute single range elements with compile-time substitution mappings
return value.map!(a => substitute(a));
}
else static if (isInputRange!Value && !is(CommonType!(ElementType!Value, ElementType!(typeof(substs[0]))) == void))
{
// not implemented yet, fallback to runtime variant for now
return .substitute(value, substs);
}
else
{
static assert(0, "Compile-time substitutions must be elements or ranges of the same type of ` ~ Value.stringof ~ `.");
}
}
// Substitute single values with compile-time substitution mappings.
else // static if (!is(CommonType!(Value, typeof(substs[0])) == void))
{ {
switch (value) switch (value)
{ {
@ -4733,38 +4753,22 @@ if (substs.length >= 2 && isExpressions!substs)
default: return value; default: return value;
} }
} }
/// Substitute single range elements with compile-time substitution mappings
auto substitute(R)(R r)
if (isInputRange!R && !is(CommonType!(ElementType!R, typeof(substs[0])) == void))
{
return r.map!(a => substitute(a));
}
/// Substitute subranges with compile-time substitution mappings
auto substitute(R)(R r)
if (isInputRange!R && !is(CommonType!(ElementType!R, ElementType!(typeof(substs[0]))) == void))
{
// not implemented yet, fallback to runtime variant for now
return .substitute(r, substs);
} }
} }
// In same combinations substitute needs to calculate the auto-decoded length // In same combinations substitute needs to calculate the auto-decoded length
// of its needles // of its needles
private template needsManualAutodecoding(Range, Needles...) private template hasDifferentAutodecoding(Range, Needles...)
{ {
import std.meta : anySatisfy; import std.meta : anySatisfy;
/* iff /* iff
- the needles needs auto-decoding, but the incoming range doesn't - the needles needs auto-decoding, but the incoming range doesn't (or vice versa)
- (vice versa) if the incoming range needs auto-decoding, but the needle don't
- both (range, needle) need auto-decoding and don't share the same common type - both (range, needle) need auto-decoding and don't share the same common type
*/ */
enum needlesAreNarrow = anySatisfy!(isNarrowString, Needles); enum needlesAreNarrow = anySatisfy!(isNarrowString, Needles);
enum sourceIsNarrow = isNarrowString!Range; enum sourceIsNarrow = isNarrowString!Range;
enum needsManualAutodecoding = ( sourceIsNarrow && !needlesAreNarrow) || enum hasDifferentAutodecoding = sourceIsNarrow != needlesAreNarrow ||
(!sourceIsNarrow && needlesAreNarrow) || (sourceIsNarrow && needlesAreNarrow &&
((sourceIsNarrow && needlesAreNarrow) &&
is(CommonType!(Range, Needles) == void)); is(CommonType!(Range, Needles) == void));
} }
@ -4772,18 +4776,25 @@ private template needsManualAutodecoding(Range, Needles...)
{ {
import std.meta : AliasSeq; // used for better clarity import std.meta : AliasSeq; // used for better clarity
static assert(!needsManualAutodecoding!(string, AliasSeq!(string, string))); static assert(!hasDifferentAutodecoding!(string, AliasSeq!(string, string)));
static assert(!needsManualAutodecoding!(wstring, AliasSeq!(wstring, wstring))); static assert(!hasDifferentAutodecoding!(wstring, AliasSeq!(wstring, wstring)));
static assert(!needsManualAutodecoding!(dstring, AliasSeq!(dstring, dstring))); static assert(!hasDifferentAutodecoding!(dstring, AliasSeq!(dstring, dstring)));
static assert(needsManualAutodecoding!(string, AliasSeq!(wstring, string))); // the needles needs auto-decoding, but the incoming range doesn't (or vice versa)
static assert(needsManualAutodecoding!(wstring, AliasSeq!(string, string))); static assert(hasDifferentAutodecoding!(string, AliasSeq!(wstring, wstring)));
static assert(hasDifferentAutodecoding!(string, AliasSeq!(dstring, dstring)));
static assert(hasDifferentAutodecoding!(wstring, AliasSeq!(string, string)));
static assert(hasDifferentAutodecoding!(wstring, AliasSeq!(dstring, dstring)));
static assert(hasDifferentAutodecoding!(dstring, AliasSeq!(string, string)));
static assert(hasDifferentAutodecoding!(dstring, AliasSeq!(wstring, wstring)));
static assert(needsManualAutodecoding!(dstring, AliasSeq!(string, string))); // both (range, needle) need auto-decoding and don't share the same common type
static assert(needsManualAutodecoding!(dstring, AliasSeq!(string, wstring))); static foreach (T; AliasSeq!(string, wstring, dstring))
{
static assert(needsManualAutodecoding!(string, AliasSeq!(dstring, string))); static assert(hasDifferentAutodecoding!(T, AliasSeq!(wstring, string)));
static assert(needsManualAutodecoding!(string, AliasSeq!(wstring, string))); static assert(hasDifferentAutodecoding!(T, AliasSeq!(dstring, string)));
static assert(hasDifferentAutodecoding!(T, AliasSeq!(wstring, dstring)));
}
} }
/// ditto /// ditto
@ -4880,10 +4891,10 @@ if (isInputRange!R && Substs.length >= 2 && !is(CommonType!(Substs) == void))
Hit hitNr; // hit number: 0 means no hit, otherwise index+1 to needles that matched Hit hitNr; // hit number: 0 means no hit, otherwise index+1 to needles that matched
bool hasHit; // is there a replacement hit which should be printed? bool hasHit; // is there a replacement hit which should be printed?
enum needsManualAutodecoding = .needsManualAutodecoding!(typeof(rest), Ins); enum hasDifferentAutodecoding = .hasDifferentAutodecoding!(typeof(rest), Ins);
// calculating the needle length for narrow strings might be expensive -> cache it // calculating the needle length for narrow strings might be expensive -> cache it
static if (needsManualAutodecoding) static if (hasDifferentAutodecoding)
ptrdiff_t[n] needleLengths = -1; ptrdiff_t[n] needleLengths = -1;
} }
@ -4960,12 +4971,12 @@ if (isInputRange!R && Substs.length >= 2 && !is(CommonType!(Substs) == void))
else else
{ {
auto hitLength = size_t.max; auto hitLength = size_t.max;
SWITCH: switch (hitNr - 1) switchL: switch (hitNr - 1)
{ {
static foreach (i; 0 .. n) static foreach (i; 0 .. n)
{ {
case i: case i:
static if (needsManualAutodecoding) static if (hasDifferentAutodecoding)
{ {
import std.utf : codeLength; import std.utf : codeLength;
@ -4979,7 +4990,7 @@ if (isInputRange!R && Substs.length >= 2 && !is(CommonType!(Substs) == void))
{ {
hitLength = needles[i].length; hitLength = needles[i].length;
} }
break SWITCH; break switchL;
} }
default: default:
assert(0, "hitNr should always be found"); assert(0, "hitNr should always be found");
@ -4993,7 +5004,7 @@ if (isInputRange!R && Substs.length >= 2 && !is(CommonType!(Substs) == void))
// iff the source range and the substitutions are narrow strings, // iff the source range and the substitutions are narrow strings,
// we can avoid calling the auto-decoding `popFront` (via drop) // we can avoid calling the auto-decoding `popFront` (via drop)
static if (isNarrowString!(typeof(hitValue)) && !needsManualAutodecoding) static if (isNarrowString!(typeof(hitValue)) && !hasDifferentAutodecoding)
rest = hitValue[hitLength .. $]; rest = hitValue[hitLength .. $];
else else
rest = hitValue.drop(hitLength); rest = hitValue.drop(hitLength);

View file

@ -2010,13 +2010,6 @@ if (isInputRange!(Unqual!Range) &&
return _maxAvailable == 0 || source.empty; return _maxAvailable == 0 || source.empty;
} }
static if (is(typeof((cast(const R) source).empty)))
/// ditto
@property bool empty() const
{
return _maxAvailable == 0 || source.empty;
}
/// ditto /// ditto
@property auto ref front() @property auto ref front()
{ {