Re: Merge 2 structs together (into a single struct)?

2021-09-16 Thread jfondren via Digitalmars-d-learn
On Friday, 17 September 2021 at 05:01:36 UTC, james.p.leblanc 
wrote:
Again, thanks to you and many of the D community with helping 
to learn and

appreciate the capabilities of D.  It is nice to be here.


Yeah. The improved joinStruct is nice enough that I think it's 
probably a good thing to do.


And there's this, some kind of Jai innovation:

```d
struct Object {
float[2] position, velocity, facing;
float size;
}

struct Player {
mixin parent!Object;
int hp;
}

mixin template parent(Struct) {
static foreach (i, alias f; Struct.tupleof) {
mixin("typeof(f) ", __traits(identifier, f), " = 
Struct.init.tupleof[i];");

}
}

void main() {
import std.stdio : writeln;

writeln(Player([0, 0], [0, 0], [0, -1], 5.0, 100));
}
```


Re: Merge 2 structs together (into a single struct)?

2021-09-16 Thread james.p.leblanc via Digitalmars-d-learn

On Friday, 17 September 2021 at 00:36:42 UTC, ag0aep6g wrote:

On 16.09.21 22:53, jfondren wrote:

string joinstruct(A, B)(string name) {


struct JoinStruct(Structs ...)
{
static foreach (S; Structs)
{
static foreach (i, alias f; S.tupleof)
{
mixin("typeof(f) ", __traits(identifier, f),
" = S.init.tupleof[i];");




Ali, jfondren, ag0aep6g,

All of your responses are greatly appreciated.  I have done test 
implementations
of them all, and they work well with my intended application. 
(Also, I learned

something new from all of them).

The struct mixin template appears to be quite robust and elegant. 
 So, I include a
simple implementation for any future readers to take it for a 
"test drive".


```d

import std.stdio;
import std.traits;

template JoinStruct(Structs ...)
{
   static foreach (S; Structs)
   {
  static foreach(i, alias f; S.tupleof)
  {
 mixin("typeof(f) ", __traits(identifier, f), " = 
S.init.tupleof[i];");

  }
   }
}

void main(){

   struct A {
  int alpha;
  float x = 1.23;
   }

   struct B {
  int beta;
  float y = 4.4;
  string s = "this is fine.";
   }

   struct C {
  int gamma = 42;
  double z = 1.2e8;
  string t = "if this was named 's', duplicate would be 
detected at compile time";

   }

   struct D {
  mixin JoinStruct!(A,B,C);
   }

   A a;
   B b;
   C c;

   writeln("\na:", a);
   writeln("\nb:", b);
   writeln("\nc:", c)
   auto d = D();
   writeln("\nd:", d);
}

```

My next steps would be to include some UDA's to ease the getopt 
building
for command line arguments.  There is a sketch from Jesse 
Phillips at


https://dev.to/jessekphillips/argument-parsing-into-structure-4p4n

For example:

```d
// Specify The Parameter Structure
struct Options
{
   @Option("threads", "t")
   @Help("Number of threads to use.")
   size_t threads;

   @Option("file")
   @Help("Input files")
   string[] files;
}
```

Again, thanks to you and many of the D community with helping to 
learn and

appreciate the capabilities of D.  It is nice to be here.

Best Regards,
James





Re: Merge 2 structs together (into a single struct)?

2021-09-16 Thread ag0aep6g via Digitalmars-d-learn

On 16.09.21 22:53, jfondren wrote:

string joinstruct(A, B)(string name) {
     string s = "struct " ~ name ~ " {";
     alias memA = __traits(allMembers, A);
     alias memB = __traits(allMembers, B);
     alias initA = A.init.tupleof;
     alias initB = B.init.tupleof;
     static foreach (i; 0 .. memA.length) {
     s ~= typeof(__traits(getMember, A, memA[i])).stringof;
     s ~= " ";
     s ~= memA[i];
     s ~= " = ";
     s ~= initA[i].stringof;
     s ~= ";\n";
     }
     static foreach (i; 0 .. memB.length) {
     s ~= typeof(__traits(getMember, B, memB[i])).stringof;
     s ~= " ";
     s ~= memB[i];
     s ~= " = ";
     s ~= initB[i].stringof;
     s ~= ";\n";
     }
     s ~= "}";
     return s;
}


As a rule of thumb, don't use `stringof` for string mixins. There's 
usually a better way.


In this case, if you make `joinstruct` a struct template, you can use 
the types and init values of the fields directly, without converting 
them to strings and back. Only the names need to be mixed in as strings.



struct JoinStruct(Structs ...)
{
static foreach (S; Structs)
{
static foreach (i, alias f; S.tupleof)
{
mixin("typeof(f) ", __traits(identifier, f),
" = S.init.tupleof[i];");
}
}
}



Re: Merge 2 structs together (into a single struct)?

2021-09-16 Thread jfondren via Digitalmars-d-learn
On Thursday, 16 September 2021 at 20:12:03 UTC, james.p.leblanc 
wrote:

Is there some obvious, and simple solution to this
conundrum of mine?


I would consider AAs.

```d
struct A {
int alpha;
float x = 1.23;
}

struct B {
int beta;
float y = 4.4;
string s = "this is fine.";
}

string joinstruct(A, B)(string name) {
string s = "struct " ~ name ~ " {";
alias memA = __traits(allMembers, A);
alias memB = __traits(allMembers, B);
alias initA = A.init.tupleof;
alias initB = B.init.tupleof;
static foreach (i; 0 .. memA.length) {
s ~= typeof(__traits(getMember, A, memA[i])).stringof;
s ~= " ";
s ~= memA[i];
s ~= " = ";
s ~= initA[i].stringof;
s ~= ";\n";
}
static foreach (i; 0 .. memB.length) {
s ~= typeof(__traits(getMember, B, memB[i])).stringof;
s ~= " ";
s ~= memB[i];
s ~= " = ";
s ~= initB[i].stringof;
s ~= ";\n";
}
s ~= "}";
return s;
}

unittest {
mixin(joinstruct!(A, B)("C"));
import std.stdio;
writeln(C());
}
```


Re: Merge 2 structs together (into a single struct)?

2021-09-16 Thread Ali Çehreli via Digitalmars-d-learn

On 9/16/21 1:12 PM, james.p.leblanc wrote:

> I really thought that this would be a simple enough
> small project in meta programming/reflection.

It should be doable. One question is how to resolve conflicting members 
of the two structs, which can be defaulted to one of the policies "cause 
compilation error", "do name mangle", "ignore second", etc.


>  the point of this is really to use the struct AB
> for getopt reading of command line options.

I pass local variables to getopt and then construct a struct from them:

  int a;
  double d;

  getopt(/* ... */, , /* ... */, );

  myFunction(MyStruct(a, d));

Do you want to pass members of a struct to getopt?

  auto m = MyStruct();

  getopt(/* ... */, , /* ... */, );

Ali



Merge 2 structs together (into a single struct)?

2021-09-16 Thread james.p.leblanc via Digitalmars-d-learn

Dear All,

I really thought that this would be a simple enough
small project in meta programming/reflection.  Consisely,
merge two structures, which are coming from two different
elements of the code base.  (One contains standard input
options for getopt, and the other is for user customization
for getopt.)

And while there are many hints, and partial solutions among
forum posts, and books, my many attempts have not been
successful.

Is there some obvious, and simple solution to this
conundrum of mine?

```d
struct A
{
   int alpha;
   float x = 1.23;
}

struct B
{
   int beta;
   float y = 4.4;
   string s = "this is fine.";
}

```
  some static foreach magic, and mixins later ... we have the 
merger


```d
 struct AB
{
   int alpha;
   float x = 1.23;
   int beta;
   float y = 4.4;
   string s = "this is fine.";
}
```
... the point of this is really to use the struct AB
for getopt reading of command line options.

All pointers, tips and info are greatly appreciated.
Best Regards,
James