Reduce the number of isAggregateType!T checks

Some are redundant. Others can be replaced by cheaper traits checks.
This commit is contained in:
Nathan Sashihara 2020-08-02 10:37:29 -07:00 committed by The Dlang Bot
parent 17ae8fc9be
commit 99e390486c
4 changed files with 23 additions and 26 deletions

View file

@ -635,13 +635,12 @@ bool isASCII(dchar c) @safe pure nothrow @nogc
auto toLower(C)(C c) auto toLower(C)(C c)
if (is(C : dchar)) if (is(C : dchar))
{ {
import std.traits : isAggregateType, OriginalType, Unqual; import std.traits : OriginalType;
alias OC = OriginalType!C; static if (!__traits(isScalar, C))
static if (isAggregateType!OC)
alias R = dchar; alias R = dchar;
else else static if (is(immutable OriginalType!C == immutable OC, OC))
alias R = Unqual!OC; alias R = OC;
return isUpper(c) ? cast(R)(cast(R) c + 'a' - 'A') : cast(R) c; return isUpper(c) ? cast(R)(cast(R) c + 'a' - 'A') : cast(R) c;
} }
@ -698,13 +697,12 @@ if (is(C : dchar))
auto toUpper(C)(C c) auto toUpper(C)(C c)
if (is(C : dchar)) if (is(C : dchar))
{ {
import std.traits : isAggregateType, OriginalType, Unqual; import std.traits : OriginalType;
alias OC = OriginalType!C; static if (!__traits(isScalar, C))
static if (isAggregateType!OC)
alias R = dchar; alias R = dchar;
else else static if (is(immutable OriginalType!C == immutable OC, OC))
alias R = Unqual!OC; alias R = OC;
return isLower(c) ? cast(R)(cast(R) c - ('a' - 'A')) : cast(R) c; return isLower(c) ? cast(R)(cast(R) c - ('a' - 'A')) : cast(R) c;
} }

View file

@ -3877,7 +3877,7 @@ private enum HasToStringResult
private template hasToString(T, Char) private template hasToString(T, Char)
{ {
static if (isPointer!T && !isAggregateType!T) static if (isPointer!T)
{ {
// X* does not have toString, even if X is aggregate type has toString. // X* does not have toString, even if X is aggregate type has toString.
enum hasToString = HasToStringResult.none; enum hasToString = HasToStringResult.none;

View file

@ -381,7 +381,7 @@ void put(R, E)(ref R r, E e)
} }
//Optional optimization block for straight up array to array copy. //Optional optimization block for straight up array to array copy.
else static if (isDynamicArray!R && else static if (isDynamicArray!R &&
!(isAutodecodableString!R && !isAggregateType!R) && !isAutodecodableString!R &&
isDynamicArray!E && isDynamicArray!E &&
is(typeof(r[] = e[]))) is(typeof(r[] = e[])))
{ {
@ -2232,7 +2232,7 @@ equivalent to `popFront(array)`. For $(GLOSSARY narrow strings),
point). point).
*/ */
void popFront(T)(scope ref inout(T)[] a) @safe pure nothrow @nogc void popFront(T)(scope ref inout(T)[] a) @safe pure nothrow @nogc
if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[])) if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{ {
assert(a.length, "Attempting to popFront() past the end of an array of " ~ T.stringof); assert(a.length, "Attempting to popFront() past the end of an array of " ~ T.stringof);
a = a[1 .. $]; a = a[1 .. $];
@ -2255,7 +2255,7 @@ if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[
/// ditto /// ditto
void popFront(C)(scope ref inout(C)[] str) @trusted pure nothrow void popFront(C)(scope ref inout(C)[] str) @trusted pure nothrow
if (isAutodecodableString!(C[]) && !isAggregateType!(C[])) if (isAutodecodableString!(C[]))
{ {
import std.algorithm.comparison : min; import std.algorithm.comparison : min;
@ -2347,7 +2347,7 @@ equivalent to `popBack(array)`. For $(GLOSSARY narrow strings), $(D
popFront) automatically eliminates the last $(GLOSSARY code point). popFront) automatically eliminates the last $(GLOSSARY code point).
*/ */
void popBack(T)(scope ref inout(T)[] a) @safe pure nothrow @nogc void popBack(T)(scope ref inout(T)[] a) @safe pure nothrow @nogc
if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[])) if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{ {
assert(a.length); assert(a.length);
a = a[0 .. $ - 1]; a = a[0 .. $ - 1];
@ -2370,7 +2370,7 @@ if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[
/// ditto /// ditto
void popBack(T)(scope ref inout(T)[] a) @safe pure void popBack(T)(scope ref inout(T)[] a) @safe pure
if (isAutodecodableString!(T[]) && !isAggregateType!(T[])) if (isAutodecodableString!(T[]))
{ {
import std.utf : strideBack; import std.utf : strideBack;
assert(a.length, "Attempting to popBack() past the front of an array of " ~ T.stringof); assert(a.length, "Attempting to popBack() past the front of an array of " ~ T.stringof);
@ -2429,7 +2429,7 @@ front) automatically returns the first $(GLOSSARY code point) as _a $(D
dchar). dchar).
*/ */
@property ref inout(T) front(T)(return scope inout(T)[] a) @safe pure nothrow @nogc @property ref inout(T) front(T)(return scope inout(T)[] a) @safe pure nothrow @nogc
if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[])) if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{ {
assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof); assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
return a[0]; return a[0];
@ -2458,7 +2458,7 @@ if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[
/// ditto /// ditto
@property dchar front(T)(scope const(T)[] a) @safe pure @property dchar front(T)(scope const(T)[] a) @safe pure
if (isAutodecodableString!(T[]) && !isAggregateType!(T[])) if (isAutodecodableString!(T[]))
{ {
import std.utf : decode; import std.utf : decode;
assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof); assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
@ -2475,7 +2475,7 @@ back) automatically returns the last $(GLOSSARY code point) as _a $(D
dchar). dchar).
*/ */
@property ref inout(T) back(T)(return scope inout(T)[] a) @safe pure nothrow @nogc @property ref inout(T) back(T)(return scope inout(T)[] a) @safe pure nothrow @nogc
if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[])) if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{ {
assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof); assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof);
return a[$ - 1]; return a[$ - 1];
@ -2502,7 +2502,7 @@ if (!(isAutodecodableString!(T[]) && !isAggregateType!(T[])) && !is(T[] == void[
/// ditto /// ditto
// Specialization for strings // Specialization for strings
@property dchar back(T)(scope const(T)[] a) @safe pure @property dchar back(T)(scope const(T)[] a) @safe pure
if (isAutodecodableString!(T[]) && !isAggregateType!(T[])) if (isAutodecodableString!(T[]))
{ {
import std.utf : decode, strideBack; import std.utf : decode, strideBack;
assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof); assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof);

View file

@ -5638,7 +5638,6 @@ Note: Trying to use returned value will result in a
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::// //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
private template AliasThisTypeOf(T) private template AliasThisTypeOf(T)
if (isAggregateType!T)
{ {
alias members = __traits(getAliasThis, T); alias members = __traits(getAliasThis, T);
@ -6093,7 +6092,7 @@ template BuiltinTypeOf(T)
/** /**
* Detect whether `T` is a built-in boolean type. * Detect whether `T` is a built-in boolean type.
*/ */
enum bool isBoolean(T) = is(BooleanTypeOf!T) && !isAggregateType!T; enum bool isBoolean(T) = __traits(isUnsigned, T) && is(BooleanTypeOf!T);
/// ///
@safe unittest @safe unittest
@ -6118,7 +6117,7 @@ enum bool isBoolean(T) = is(BooleanTypeOf!T) && !isAggregateType!T;
* Detect whether `T` is a built-in integral type. Types `bool`, * Detect whether `T` is a built-in integral type. Types `bool`,
* `char`, `wchar`, and `dchar` are not considered integral. * `char`, `wchar`, and `dchar` are not considered integral.
*/ */
enum bool isIntegral(T) = is(IntegralTypeOf!T) && !isAggregateType!T; enum bool isIntegral(T) = __traits(isIntegral, T) && is(IntegralTypeOf!T);
/// ///
@safe unittest @safe unittest
@ -6300,7 +6299,7 @@ enum bool isNumeric(T) = __traits(isArithmetic, T) && !(is(immutable T == immuta
* Detect whether `T` is a scalar type (a built-in numeric, character or * Detect whether `T` is a scalar type (a built-in numeric, character or
* boolean type). * boolean type).
*/ */
enum bool isScalarType(T) = is(T : real) && !isAggregateType!T; enum bool isScalarType(T) = __traits(isScalar, T) && is(T : real);
/// ///
@safe unittest @safe unittest
@ -6454,7 +6453,7 @@ enum bool isSigned(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T);
* The built-in char types are any of `char`, `wchar` or `dchar`, with * The built-in char types are any of `char`, `wchar` or `dchar`, with
* or without qualifiers. * or without qualifiers.
*/ */
enum bool isSomeChar(T) = is(CharTypeOf!T) && !isAggregateType!T; enum bool isSomeChar(T) = __traits(isUnsigned, T) && is(CharTypeOf!T);
/// ///
@safe unittest @safe unittest
@ -6967,7 +6966,7 @@ enum bool isSIMDVector(T) = is(T : __vector(V[N]), V, size_t N);
/** /**
* Detect whether type `T` is a pointer. * Detect whether type `T` is a pointer.
*/ */
enum bool isPointer(T) = is(T == U*, U) && !isAggregateType!T; enum bool isPointer(T) = is(T == U*, U) && __traits(isScalar, T);
@safe unittest @safe unittest
{ {