From 43f00ee83d5b45017ddef57761c5155e0e2d639c Mon Sep 17 00:00:00 2001 From: Jonathan M Davis Date: Sat, 23 Nov 2024 03:49:08 -0700 Subject: [PATCH] Fix phobos.sys.traits.isAggregateType to handle enums. The std.traits version does not take enums into account (and prior to this commit, neither does the phobos.sys version), but upon reflection, it seems like it's just likely to cause bugs if it doesn't take enums into account. Granted, enums whose base type is an aggregate type don't seem to be very common, but as a result of that, code that tests for aggregate types likely won't take them into account in the vast majority of cases, and I see no reason to not have the trait just deal with it rather than hoping that the user of the trait realizes that it's a potential issue, in which case, they would need to explicitly use OriginalType themselves to make it work for enums. In addition, this way, OriginalType doesn't even get instantiated unless the type is actually an enum, whereas the correct solution that would most likely be used otherwise would be to just always do isAggregateType!(OriginalType!T) instead of isAggregateType!T. I also put a ddoc comment on the unittest block, since I apparently missed it previously. --- phobos/sys/traits.d | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/phobos/sys/traits.d b/phobos/sys/traits.d index 595dc7a15..85b229f21 100644 --- a/phobos/sys/traits.d +++ b/phobos/sys/traits.d @@ -118,10 +118,18 @@ module phobos.sys.traits; /++ Whether the given type is an "aggregate type" - i.e. a struct, class, - interface, or union. + interface, or union. Enum types whose base type is an aggregate type are + also considered aggregate types. +/ -enum isAggregateType(T) = is(T == struct) || is(T == class) || is(T == interface) || is(T == union); +template isAggregateType(T) +{ + static if (is(T == enum)) + enum isAggregateType = isAggregateType!(OriginalType!T); + else + enum isAggregateType = is(T == struct) || is(T == class) || is(T == interface) || is(T == union); +} +/// @safe unittest { struct S {} @@ -141,6 +149,18 @@ enum isAggregateType(T) = is(T == struct) || is(T == class) || is(T == interface static assert(!isAggregateType!(S*)); static assert(!isAggregateType!(C[])); static assert(!isAggregateType!(I[string])); + + enum ES : S { a = S.init } + enum EC : C { a = C.init } + enum EI : I { a = I.init } + enum EU : U { a = U.init } + + static assert( isAggregateType!ES); + static assert( isAggregateType!EC); + static assert( isAggregateType!EI); + static assert( isAggregateType!EU); + static assert( isAggregateType!(const ES)); + static assert( isAggregateType!(const EC)); } /++