Jump to page: 1 2
Thread overview
Define an order for allMembers traits
Aug 23, 2023
Andrey Zherikov
Aug 23, 2023
Adam D Ruppe
Aug 23, 2023
Andrey Zherikov
Aug 23, 2023
Stefan Koch
Aug 23, 2023
Alexandru Ermicioi
Aug 23, 2023
Adam D Ruppe
Aug 23, 2023
Andrey Zherikov
Aug 24, 2023
John Colvin
Aug 24, 2023
Adam D Ruppe
Aug 23, 2023
Paul Backus
Aug 23, 2023
Andrey Zherikov
Aug 23, 2023
Paul Backus
Aug 23, 2023
Timon Gehr
Aug 24, 2023
Walter Bright
August 23, 2023

D doc for for __traits(allMembers, ...) says that "the order in which the strings appear in the result is not defined". Is it possible to define an order at least for some cases (I'm looking for structs actually)?

I think having guaranteed order for simple cases in beneficial:

struct S
{
  int a,b;
  string c,d;
}

assert([ __traits(allMembers, S) ] == [ "a","b","c","d" ]);

This will especially help in my use case where I need to know the order in which struct members are declared. Right now I'm using UDA with index to explicitly set an order:

struct S
{
  @UDA(1) int a;
  @UDA(2) int b;
  @UDA(3) string c;
  @UDA(4) string d;
}

Possible solution would be to use __LINE__ but it won't work in this case:

struct S
{
  @UDA int a; @UDA int b;
}

The only solution that might work is to use __traits(getLocation, ...) which complicates introspection a lot: instead of simple usage of __traits(allMembers, ...) I'll have to sort all members by location and only then iterate over them.

August 23, 2023
On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:
> Is it possible to define an order at least for some cases (I'm looking for structs actually)?

What do you do with the order of declaration?
August 24, 2023
Another way to do this (which should be defined):

```d
void main() {
    S s;

    static foreach(f; s.tupleof) {
        pragma(msg, __traits(identifier, f));
    }
}

struct S {
   int a, b;

    union {
        string c, d;
    }
}
```
August 23, 2023

On Wednesday, 23 August 2023 at 12:39:09 UTC, Adam D Ruppe wrote:

>

On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:

>

Is it possible to define an order at least for some cases (I'm looking for structs actually)?

What do you do with the order of declaration?

I'm developing a library to parse command line arguments. One type of arguments is positional argument which means that they have a position in command line.
As of now (because the order of allMembers is not defined), these arguments are attributed the following way by explicitly providing the order:

struct Params
{
    @PositionalArgument(0)
    string firstName;

    @PositionalArgument(1)
    string middleName;

    @PositionalArgument(2)
    string lastName;
}

If allMembers guarantees the order to be the same as the members are declared then the code above can be simplified to this:

struct Params
{
    @PositionalArgument
    string firstName, middleName, lastName;
}
August 23, 2023

On Wednesday, 23 August 2023 at 13:53:30 UTC, Andrey Zherikov wrote:

>

On Wednesday, 23 August 2023 at 12:39:09 UTC, Adam D Ruppe wrote:

>

On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:

>

Is it possible to define an order at least for some cases (I'm looking for structs actually)?

What do you do with the order of declaration?

I'm developing a library to parse command line arguments. One type of arguments is positional argument which means that they have a position in command line.
As of now (because the order of allMembers is not defined), these arguments are attributed the following way by explicitly providing the order:

struct Params
{
    @PositionalArgument(0)
    string firstName;

    @PositionalArgument(1)
    string middleName;

    @PositionalArgument(2)
    string lastName;
}

If allMembers guarantees the order to be the same as the members are declared then the code above can be simplified to this:

struct Params
{
    @PositionalArgument
    string firstName, middleName, lastName;
}

My 10 cents on this are:

In the general case we cannot guarantee the order of __traits(allMembers) as they might be generated by meta-programming which does not have an obvious execution order.

So the question is we guarantee lexical order in the cases where no meta programming is used to introduce members?
I think we can do that.

August 23, 2023

On Wednesday, 23 August 2023 at 14:24:46 UTC, Stefan Koch wrote:

>

...
So the question is we guarantee lexical order in the cases where no meta programming is used to introduce members?
I think we can do that.

No lexical, please. It would be worse, than order in which elements are declared.

At least with the later, you could also use it for some meaningful order, such as first declared takes priority for some action, or etc. Having it all sorted lexical would hinder it. Besides, lexical ordering can also be done already at compile time.

August 23, 2023

On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:

>

This will especially help in my use case where I need to know the order in which struct members are declared. Right now I'm using UDA with index to explicitly set an order:

struct S
{
  @UDA(1) int a;
  @UDA(2) int b;
  @UDA(3) string c;
  @UDA(4) string d;
}

For this use case, you should use .tupleof instead of __traits(allMembers), which is guaranteed by the spec to give the fields in declaration order.

August 23, 2023

On Wednesday, 23 August 2023 at 15:32:02 UTC, Paul Backus wrote:

>

For this use case, you should use .tupleof instead of __traits(allMembers), which is guaranteed by the spec to give the fields in declaration order.

This link says "The order of the fields in the tuple matches the order in which the fields are declared" for the classes. I don't see such statement for structs here.

August 23, 2023
On Wednesday, 23 August 2023 at 13:53:30 UTC, Andrey Zherikov wrote:
> ```d
> struct Params
> {
>     @PositionalArgument(0)
>     string firstName;
>
>     @PositionalArgument(1)
>     string middleName;
>
>     @PositionalArgument(2)
>     string lastName;
> }
> ```

tbh I actually prefer this code to the alternative

> If `allMembers` guarantees the order to be the same as the members are declared then the code above can be simplified to this:

but yeah, what others say about the tuple thing is prolly the best thing by spec

tho in practice allMembers is in order but relying on that might lead to troube some random day
August 23, 2023
On Wednesday, 23 August 2023 at 16:52:36 UTC, Adam D Ruppe wrote:
> but yeah, what others say about the tuple thing is prolly the best thing by spec

I don't see that the order of tupleof is specified for structs there.
« First   ‹ Prev
1 2