Skip to content

Commit

Permalink
Merge pull request #3512 from MartinNowak/fix14765
Browse files Browse the repository at this point in the history
add std.traits.isAutodecodableString() to fix Issue 14765
  • Loading branch information
MartinNowak committed Jul 23, 2015
2 parents 7281178 + 31c9630 commit 39806a8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 13 deletions.
33 changes: 33 additions & 0 deletions std/traits.d
Expand Up @@ -85,6 +85,7 @@
* $(LREF isFloatingPoint)
* $(LREF isIntegral)
* $(LREF isNarrowString)
* $(LREF isAutodecodableString)
* $(LREF isNumeric)
* $(LREF isPointer)
* $(LREF isScalarType)
Expand Down Expand Up @@ -5236,6 +5237,38 @@ unittest
}
}


/**
* Detect whether type $(D T) is a string that will be autodecoded.
*
* All arrays that use char, wchar, and their qualified versions are narrow
* strings. (Those include string and wstring).
* Aggregates that implicitly cast to narrow strings are included.
*
* Params:
* T = type to be tested
*
* Returns:
* true if T represents a string that is subject to autodecoding
*
* See Also:
* $(LREF isNarrowString)
*/
enum bool isAutodecodableString(T) = (is(T : const char[]) || is(T : const wchar[])) && !isStaticArray!T;

///
unittest
{
static struct Stringish
{
string s;
alias s this;
}
assert(isAutodecodableString!wstring);
assert(isAutodecodableString!Stringish);
assert(!isAutodecodableString!dstring);
}

/**
* Detect whether type $(D T) is a static array.
*/
Expand Down
43 changes: 30 additions & 13 deletions std/utf.d
Expand Up @@ -3079,7 +3079,7 @@ enum dchar replacementDchar = '\uFFFD';
* input range
*/

auto byCodeUnit(R)(R r) if (isNarrowString!R)
auto byCodeUnit(R)(R r) if (isAutodecodableString!R)
{
/* Turn an array into an InputRange.
*/
Expand All @@ -3102,9 +3102,12 @@ auto byCodeUnit(R)(R r) if (isNarrowString!R)
r = r[0 .. $-1];
}

auto opSlice(size_t lower, size_t upper)
static if (!isAggregateType!R)
{
return ByCodeUnitImpl(r[lower..upper]);
auto opSlice(size_t lower, size_t upper)
{
return ByCodeUnitImpl(r[lower..upper]);
}
}

@property size_t length() const
Expand All @@ -3113,23 +3116,26 @@ auto byCodeUnit(R)(R r) if (isNarrowString!R)
}
alias opDollar = length;

@property auto save()
static if (!isAggregateType!R)
{
return ByCodeUnitImpl(r.save);
@property auto save()
{
return ByCodeUnitImpl(r.save);
}
}

private:
R r;
}

static assert(isRandomAccessRange!ByCodeUnitImpl);
static assert(isAggregateType!R || isRandomAccessRange!ByCodeUnitImpl);

return ByCodeUnitImpl(r);
}

/// Ditto
auto ref byCodeUnit(R)(R r)
if (!isNarrowString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
if (!isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
{
// byCodeUnit for ranges and dchar[] is a no-op
return r;
Expand Down Expand Up @@ -3204,6 +3210,17 @@ pure nothrow @nogc unittest
ret.popFront();
assert(ret.front == 'μ');
}
{
static struct Stringish
{
string s;
alias s this;
}

auto fn = Stringish("test.d");
auto x = fn.byCodeUnit();
assert(x.front == 't');
}
}

/****************************
Expand All @@ -3220,7 +3237,7 @@ pure nothrow @nogc unittest
* input range
*/

auto byChar(R)(R r) if (isNarrowString!R)
auto byChar(R)(R r) if (isAutodecodableString!R)
{
/* This and the following two serve as adapters to convert arrays to ranges,
* so the following three
Expand All @@ -3239,7 +3256,7 @@ auto byChar(R)(R r) if (isNarrowString!R)
}

/// Ditto
auto byWchar(R)(R r) if (isNarrowString!R)
auto byWchar(R)(R r) if (isAutodecodableString!R)
{
alias tchar = Unqual!(ElementEncodingType!R);

Expand All @@ -3254,7 +3271,7 @@ auto byWchar(R)(R r) if (isNarrowString!R)
}

/// Ditto
auto byDchar(R)(R r) if (isNarrowString!R)
auto byDchar(R)(R r) if (isAutodecodableString!R)
{
alias tchar = Unqual!(ElementEncodingType!R);

Expand All @@ -3264,7 +3281,7 @@ auto byDchar(R)(R r) if (isNarrowString!R)

/// Ditto
auto ref byChar(R)(R r)
if (!isNarrowString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
if (!isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
{
alias tchar = Unqual!(ElementEncodingType!R);

Expand Down Expand Up @@ -3427,7 +3444,7 @@ pure nothrow @nogc unittest

/// Ditto
auto ref byWchar(R)(R r)
if (!isNarrowString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
if (!isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
{
alias tchar = Unqual!(ElementEncodingType!R);

Expand Down Expand Up @@ -3564,7 +3581,7 @@ pure nothrow @nogc unittest

/// Ditto
auto ref byDchar(R)(R r)
if (!isNarrowString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
if (!isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))
{
alias tchar = Unqual!(ElementEncodingType!R);

Expand Down

0 comments on commit 39806a8

Please sign in to comment.