Add FieldNames, FieldSymbols, and FieldTypes to phobos.sys.traits. #8986
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
FieldNames is roughly equivalent to std.traits' FieldNameTuple, and FieldTypes is roughly equivalent to std.traits' Fields (which used to be FieldTypeTuple).
The primary difference implementation-wise is that the phobos.sys.traits versions require that the types that they're given be aggregate types. For some reason, the std.traits versions accept any type and then try to give a result that at least sort of make sense when they're given a type which isn't an aggregate type (even though they really can't, because a type which isn't an aggregate type has no fields, making any choice kind of arbitrary).
For types which aren't aggregate types, Fields gives the type back in an AliasSeq, and FieldNameTuple gives AliasSeq!"". Neither makes any sense to me. I assume that it was done so that those traits could be used in generic code and work with any type, but realistically, if you want to do anything sane with them, you need to already have verified that you're dealing with an aggregate type, since it's just going to be error-prone to do stuff like Fields!int and then get AliasSeq!int back as if it had a single field of type int (or FieldNameTuple!int and get an empty string as the name). So, the phobos.sys.traits versions simply require that you give them aggregate types to avoid that entire mess.
FieldNames evaluates to the names of the fields as strings. The "Tuple" in the name of the std.traits version is an artifact from when AliasSeqs were called TypeTuples, so I didn't keep that.
FieldTypes evaluates to the types for the fields. It's FieldTypes rather than Fields for clarity, since it's not at all obvious what Fields is supposed to give you (if I'd had to guess, I would have guessed the symbols, not the types).
FieldSymbols is new. Its usefulness is questionable, since it does almost exactly the same thing that tupleof does. However, I've included it because of the subtle issues that you get with nested structs - namely that tupleof includes a context pointer in its result, which you probably don't want (though that obviously depends on what you're doing), and FieldNames and FieldTypes don't include it (just like their std.traits counterparts don't), so it seemed like it would make it less error-prone to have FieldSymbols for the cases where symbols are needed. The documentation explains (and the examples show) the difference between FieldSymbols and tupleof so that the programmer can decide which makes more sense for their particular use case.