Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-16 Thread Basile B. via Digitalmars-d-learn

On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
Is there some nice way of achieving something like this C99 
code in D?


[...]


The 
[literal](https://www.ibm.com/docs/sr/xl-c-and-cpp-aix/13.1.0?topic=operators-compound-literal-expressions) in the C version creates an alloca too but it's hidden.


Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread Elronnd via Digitalmars-d-learn

On Friday, 15 October 2021 at 21:47:21 UTC, Paul Backus wrote:

static global(alias value) = value;


I fear there will be issues with reentrancy.


Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread russhy via Digitalmars-d-learn

On Friday, 15 October 2021 at 21:47:21 UTC, Paul Backus wrote:

On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
Is there some nice way of achieving something like this C99 
code in D?


```c
#include 

typedef struct {
int x, y;
} inputs_t;

void foo(inputs_t* optional_inputs)
{
if (!optional_inputs) {
printf("0 0\n");
} else {
printf("%d %d \n", optional_inputs->x, 
optional_inputs->y);

}
}

int main(void) {
foo(NULL); // prints 0 0
foo(&(inputs_t){.x = 5, .y = 6}); // prints 5 6
}
```


```d
static global(alias value) = value;

struct Inputs { int x, y; }

void foo(Inputs* inputs)
{
import std.stdio;
if (inputs is null)
writeln("0 0");
else
writeln(inputs.x, " ", inputs.y);
}

void main()
{
foo(null);
foo(!(Inputs(5, 6)));
}
```



Nice trick, so far Paul's answer is the cleanest, 0 imports, 
doesn't change the signature of the method, and he doesn't create 
overloading


I remember i was once trying to achieve the same as OP, i ended 
up just using a local variable


Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread Tejas via Digitalmars-d-learn

On Friday, 15 October 2021 at 21:19:35 UTC, jfondren wrote:

On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
Is there some nice way of achieving something like this C99 
code in D?


option 1: use an intermediate lambda:

```d
import std.stdio;

struct inputs_t {
int x, y;
} // no ; needed here

void foo(inputs_t* optional_inputs) {
if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, " ", optional_inputs.y);
}
}

void main() {
import std.functional : pipe;

foo(null); // prints 0 0
inputs_t(5, 6).pipe!(s => foo()); // prints 5 6
}
```

option 2: use a class

```d
class inputs_t {
int x, y;
this(int x, int y) {
this.x = x;
this.y = y;
}
}

void foo(inputs_t optional_inputs) {
import std.stdio : writeln;

if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, " ", optional_inputs.y);
}
}

void main() {
foo(null);
foo(new inputs_t(5, 6));
}
```

option 3: use std.sumtype

```d
import std.sumtype;

struct Point {
int x, y;
}

alias Input = SumType!(Point, typeof(null));

void foo(Input inputs) {
import std.stdio : writeln;

inputs.match!(
(typeof(null) _) => writeln("0 0"),
(Point p) => writeln(p.x, " ", p.y),
);
}

void main() {
foo(null.Input);
foo(Point(5, 6).Input);
}
```

option 4: use overloading

```d
import std.stdio : writeln;

struct Point {
int x, y;
}

void foo() {
writeln("0 0");
}
void foo(Point p) {
writeln(p.x, " ", p.y);
}

void main() {
foo();
foo(Point(5, 6));
}
```

option 5: use S.init, when your exceptional value is handled 
the same


```d
struct Point {
int x, y;
}

void foo(Point p = Point.init) {
import std.stdio : writeln;

writeln(p.x, " ", p.y);
}

void main() {
foo();// 0 0
foo(Point.init);  // 0 0
foo(Point(5, 6)); // 5 6
}
```


No need to use `class` to get a reference type out of `new`, it 
works on `struct`s just fine:


```d
import std.stdio;

struct inputs_t {
int x, y;
}


void foo(inputs_t* optional_inputs)
{
if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, " ", optional_inputs.y);
}
}

void main() {
foo(null); // prints 0 0
foo(new inputs_t(5,6));
}
```

If you dislike using new for some reason:

```d
import std.stdio;

struct inputs_t {
int x, y;
}

T* byRef(T)(auto ref T a) {  //Use only if you don't want to 
write new for some reason

auto __internal_var__ = new T(a.tupleof);
return __internal_var__;
}


void foo(inputs_t* optional_inputs)
{
if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, " ", optional_inputs.y);
}
}

void main() {
foo(null); // prints 0 0
foo(inputs_t(5, 6).byRef);
}
```

Thirdly, we can use the `rvalue reference` trick in d-idioms:
https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-ref-and-then-not-using-it

It uses template mixins and requires that you inject it in every 
single `struct` declaration, but is also more efficient since it 
avoids an unnecessary copy.




Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread Paul Backus via Digitalmars-d-learn

On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
Is there some nice way of achieving something like this C99 
code in D?


```c
#include 

typedef struct {
int x, y;
} inputs_t;

void foo(inputs_t* optional_inputs)
{
if (!optional_inputs) {
printf("0 0\n");
} else {
printf("%d %d \n", optional_inputs->x, 
optional_inputs->y);

}
}

int main(void) {
foo(NULL); // prints 0 0
foo(&(inputs_t){.x = 5, .y = 6}); // prints 5 6
}
```


```d
static global(alias value) = value;

struct Inputs { int x, y; }

void foo(Inputs* inputs)
{
import std.stdio;
if (inputs is null)
writeln("0 0");
else
writeln(inputs.x, " ", inputs.y);
}

void main()
{
foo(null);
foo(!(Inputs(5, 6)));
}
```


Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread jfondren via Digitalmars-d-learn

On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
Is there some nice way of achieving something like this C99 
code in D?


option 1: use an intermediate lambda:

```d
import std.stdio;

struct inputs_t {
int x, y;
} // no ; needed here

void foo(inputs_t* optional_inputs) {
if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, " ", optional_inputs.y);
}
}

void main() {
import std.functional : pipe;

foo(null); // prints 0 0
inputs_t(5, 6).pipe!(s => foo()); // prints 5 6
}
```

option 2: use a class

```d
class inputs_t {
int x, y;
this(int x, int y) {
this.x = x;
this.y = y;
}
}

void foo(inputs_t optional_inputs) {
import std.stdio : writeln;

if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, " ", optional_inputs.y);
}
}

void main() {
foo(null);
foo(new inputs_t(5, 6));
}
```

option 3: use std.sumtype

```d
import std.sumtype;

struct Point {
int x, y;
}

alias Input = SumType!(Point, typeof(null));

void foo(Input inputs) {
import std.stdio : writeln;

inputs.match!(
(typeof(null) _) => writeln("0 0"),
(Point p) => writeln(p.x, " ", p.y),
);
}

void main() {
foo(null.Input);
foo(Point(5, 6).Input);
}
```

option 4: use overloading

```d
import std.stdio : writeln;

struct Point {
int x, y;
}

void foo() {
writeln("0 0");
}
void foo(Point p) {
writeln(p.x, " ", p.y);
}

void main() {
foo();
foo(Point(5, 6));
}
```

option 5: use S.init, when your exceptional value is handled the 
same


```d
struct Point {
int x, y;
}

void foo(Point p = Point.init) {
import std.stdio : writeln;

writeln(p.x, " ", p.y);
}

void main() {
foo();// 0 0
foo(Point.init);  // 0 0
foo(Point(5, 6)); // 5 6
}
```


Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread SomeGuy via Digitalmars-d-learn
You could use `Nullable` from the standard library to achieve 
something similar, but it isn't as simple/nice as your C99 
compound literal example:


```D
import std.stdio;
import std.typecons; // 
https://dlang.org/phobos/std_typecons.html#Nullable


struct inputs_t { int x, y; };

void foo(Nullable!inputs_t optional_inputs)
{
if (optional_inputs.isNull) {
writeln("0 0");
} else {
auto non_null = optional_inputs.get;
writeln(non_null.x, " ", non_null.y);
}
}

void main() {
foo(Nullable!(inputs_t)()); // prints 0 0
foo(inputs_t(5, 6).nullable); // prints 5 6
}
```



How to make a function that accepts optional struct but can accept struct literal too

2021-10-15 Thread JN via Digitalmars-d-learn
Is there some nice way of achieving something like this C99 code 
in D?


```c
#include 

typedef struct {
int x, y;
} inputs_t;

void foo(inputs_t* optional_inputs)
{
if (!optional_inputs) {
printf("0 0\n");
} else {
printf("%d %d \n", optional_inputs->x, 
optional_inputs->y);

}
}

int main(void) {
foo(NULL); // prints 0 0
foo(&(inputs_t){.x = 5, .y = 6}); // prints 5 6
}
```

below code won't work. Yes, I know I can just use a local 
variable in this case and pass a pointer, but I'd like to get it 
to work with literal structs too.


```d
import std.stdio;

struct inputs_t {
int x, y;
};

void foo(inputs_t* optional_inputs)
{
if (!optional_inputs) {
writeln("0 0");
} else {
writeln(optional_inputs.x, optional_inputs.y);
}
}

void main() {
foo(null); // prints 0 0
foo(&(inputs_t(5, 6))); // error: inputs_t(5,6) is not an 
lvalue and cannot be modified

}
```