Skip to content

Commit

Permalink
fix isSomeString and StringTypeOf
Browse files Browse the repository at this point in the history
additionally DynamicArrayTypeOf and StaticArrayTypeOf considers enums based on arrays
  • Loading branch information
9rnsr committed Nov 27, 2012
1 parent 108761f commit d31e45a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 27 deletions.
4 changes: 2 additions & 2 deletions std/conv.d
Expand Up @@ -465,7 +465,7 @@ When source type supports member template function opCast, is is used.
*/
T toImpl(T, S)(S value)
if (is(typeof(S.init.opCast!T()) : T) &&
!(isSomeString!T && !is(T == enum) && !isAggregateType!T))
!(isSomeString!T && !is(T == enum)))
{
return value.opCast!T();
}
Expand Down Expand Up @@ -780,7 +780,7 @@ $(UL
T toImpl(T, S)(S value)
if (!(isImplicitlyConvertible!(S, T) &&
!isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
(isSomeString!T && !is(T == enum) && !isAggregateType!T))
(isSomeString!T && !is(T == enum)))
{
static if (isSomeString!S && !is(S == enum) && value[0].sizeof == ElementEncodingType!T.sizeof)
{
Expand Down
10 changes: 5 additions & 5 deletions std/format.d
Expand Up @@ -1637,7 +1637,7 @@ unittest
Strings are formatted like $(D printf) does.
*/
void formatValue(Writer, T, Char)(Writer w, T obj, ref FormatSpec!Char f)
if (isSomeString!T && !isStaticArray!T && !is(T == enum) && !hasToString!(T, Char))
if (is(StringTypeOf!T) && !isStaticArray!T && !is(T == enum) && !hasToString!(T, Char))
{
Unqual!(StringTypeOf!T) val = obj; // for `alias this`, see bug5371
formatRange(w, val, f);
Expand Down Expand Up @@ -1703,7 +1703,7 @@ unittest // Test for issue 8310
$(LI Const array is converted to input range by removing its qualifier.))
*/
void formatValue(Writer, T, Char)(Writer w, T obj, ref FormatSpec!Char f)
if (isDynamicArray!T && !isSomeString!T && !is(T == enum) && !hasToString!(T, Char))
if (isDynamicArray!T && !is(StringTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
{
static if (is(const(ArrayTypeOf!T) == const(void[])))
{
Expand Down Expand Up @@ -1906,7 +1906,7 @@ if (isInputRange!T)
static if (is(CharTypeOf!(ElementType!T)))
if (f.spec == 's')
{
static if (isSomeString!T)
static if (is(StringTypeOf!T))
{
auto s = val[0 .. f.precision < $ ? f.precision : $];
if (!f.flDash)
Expand Down Expand Up @@ -2083,7 +2083,7 @@ private void formatChar(Writer)(Writer w, in dchar c, in char quote)
// undocumented
// string elements are formatted like UTF-8 string literals.
void formatElement(Writer, T, Char)(Writer w, T val, ref FormatSpec!Char f)
if (isSomeString!T && !is(T == enum))
if (is(StringTypeOf!T) && !is(T == enum))
{
StringTypeOf!T str = val; // bug 8015

Expand Down Expand Up @@ -2168,7 +2168,7 @@ if (is(CharTypeOf!T) && !is(T == enum))
// undocumented
// Maybe T is noncopyable struct, so receive it by 'auto ref'.
void formatElement(Writer, T, Char)(Writer w, auto ref T val, ref FormatSpec!Char f)
if (!isSomeString!T && !is(CharTypeOf!T) || is(T == enum))
if (!is(StringTypeOf!T) && !is(CharTypeOf!T) || is(T == enum))
{
formatValue(w, val, f);
}
Expand Down
47 changes: 27 additions & 20 deletions std/traits.d
Expand Up @@ -3801,7 +3801,9 @@ template StaticArrayTypeOf(T)
{
inout(U[n]) idx(U, size_t n)( inout(U[n]) );

static if (is(typeof(idx(defaultInit!T)) X))
static if (is(T == enum))
alias .StaticArrayTypeOf!(OriginalType!T) StaticArrayTypeOf;
else static if (is(typeof(idx(defaultInit!T)) X))
alias X StaticArrayTypeOf;
else
static assert(0, T.stringof~" is not a static array type");
Expand Down Expand Up @@ -3832,7 +3834,9 @@ template DynamicArrayTypeOf(T)
{
inout(U[]) idx(U)( inout(U[]) );

static if (is(typeof(idx(defaultInit!T)) X))
static if (is(T == enum))
alias .DynamicArrayTypeOf!(OriginalType!T) DynamicArrayTypeOf;
else static if (is(typeof(idx(defaultInit!T)) X))
{
alias typeof(defaultInit!T[0]) E;

Expand Down Expand Up @@ -3884,9 +3888,21 @@ unittest

/*
*/
template StringTypeOf(T) if (isSomeString!T)
template StringTypeOf(T)
{
alias ArrayTypeOf!T StringTypeOf;
static if (is(T == typeof(null)))
{
// It is impossible to determine exact string type from typeof(null) -
// it means that StringTypeOf!(typeof(null)) is undefined.
// Then this behavior is convenient for template constraint.
static assert(0, T.stringof~" is not a string type");
}
else static if (is(T : const char[]) || is(T : const wchar[]) || is(T : const dchar[]))
{
alias ArrayTypeOf!T StringTypeOf;
}
else
static assert(0, T.stringof~" is not a string type");
}

unittest
Expand Down Expand Up @@ -4191,29 +4207,20 @@ unittest
}

/**
Detect whether we can treat T as one of the built-in string types.
Detect whether $(D T) is one of the built-in string types.
*/
template isSomeString(T)
{
static if (is(T == typeof(null)))
{
// It is impossible to determine exact string type from typeof(null) -
// it means that StringTypeOf!(typeof(null)) is undefined.
// Then this behavior is convenient for template constraint.
enum isSomeString = false;
}
else
enum isSomeString = isNarrowString!T || is(T : const(dchar[]));
enum isSomeString = is(StringTypeOf!T) && !isAggregateType!T;
}

unittest
{
static assert( isSomeString!(char[]));
static assert( isSomeString!(dchar[]));
static assert( isSomeString!string);
static assert( isSomeString!wstring);
static assert( isSomeString!dstring);
static assert( isSomeString!(char[4]));
foreach (T; TypeTuple!(char[], dchar[], string, wstring, dstring, char[4]))
{
static assert( isSomeString!( T ));
static assert(!isSomeString!(SubTypeOf!(T)));
}

static assert(!isSomeString!int);
static assert(!isSomeString!(int[]));
Expand Down

0 comments on commit d31e45a

Please sign in to comment.