Skip to content

Commit

Permalink
Fix phobos.sys.traits.isAggregateType to handle enums.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jmdavis authored and dlang-bot committed Nov 23, 2024
1 parent 08638dd commit 43f00ee
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions phobos/sys/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand All @@ -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));
}

/++
Expand Down

0 comments on commit 43f00ee

Please sign in to comment.