Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-12 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:




When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor how 
to fix it.  Does anybody know what's going on?


frame beat me to it, but it may well be that you're getting -1. 
[The documentation][1] says that a window that has already been 
destroyed will result in the `hWnd` parameter being invalid, 
which will cause the function to return -1.



[1]: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage#return-value


Re: Any UML generators for D code?

2021-08-12 Thread rikki cattermole via Digitalmars-d-learn



On 13/08/2021 9:40 AM, russhy wrote:

also this but it's pretty old: https://github.com/rikkimax/Duml


It was a neat idea duml of mine, but I wouldn't recommend going down the 
path of CTFE for this.


Best to write a tool using dmd-fe instead.


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-12 Thread frame via Digitalmars-d-learn
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:


When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor how 
to fix it.  Does anybody know what's going on?


AFAIK GetMessage() may return -1 if some error happend, so your 
loop won't exit.





Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-12 Thread Ruby The Roobster via Digitalmars-d-learn

Here is the message loop:
```d
while(GetMessage(&msg, hwnd,0,0))   {
   if(msg.message == WM_QUIT)
  break;
   TranslateMessage(&msg);
   DispatchMessage(&msg);
}
```
The WndProc(LRESULT CALLBACK):
```d
extern(Windows)
LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM 
lparam) nothrow	{

switch(msg) {
case WM_CREATE:
//...
return 0;
break;
case WM_DESTROY:
try {
entity.terminate();
}
catch(Throwable e)  {
PostQuitMessage(1);
}
PostQuitMessage(0);
break;
default:
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
```

When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor how 
to fix it.  Does anybody know what's going on?


Re: Any UML generators for D code?

2021-08-12 Thread russhy via Digitalmars-d-learn

On Thursday, 12 August 2021 at 21:11:24 UTC, JN wrote:
I'd like to see the relationships between my D classes in a 
graphical form. Is there any tool that supports that?



found this: https://code.dlang.org/packages/depend

also this but it's pretty old: https://github.com/rikkimax/Duml



Any UML generators for D code?

2021-08-12 Thread JN via Digitalmars-d-learn
I'd like to see the relationships between my D classes in a 
graphical form. Is there any tool that supports that?


Re: Unnable to join Discord

2021-08-12 Thread Tejas via Digitalmars-d-learn

On Thursday, 12 August 2021 at 18:11:20 UTC, nayy wrote:

Hi

I cannot seems to be able to join the discord server

It gives me the following error: "unable to accept invit"

Is the invitation link expired? 
https://dlang.org/community.html https://discord.gg/bMZk9Q4


I joined last week with the same link.
It worked.

Try updating your app, maybe?


Unnable to join Discord

2021-08-12 Thread nayy via Digitalmars-d-learn

Hi

I cannot seems to be able to join the discord server

It gives me the following error: "unable to accept invit"

Is the invitation link expired? https://dlang.org/community.html 
https://discord.gg/bMZk9Q4


Re: Cannot catch exception in debug mode

2021-08-12 Thread frame via Digitalmars-d-learn

On Thursday, 12 August 2021 at 03:46:00 UTC, kinke wrote:


@frame: Please file an issue.


https://issues.dlang.org/show_bug.cgi?id=22205


Re: I do not understand copy constructors

2021-08-12 Thread Ali Çehreli via Digitalmars-d-learn

On 8/12/21 4:32 AM, Paul Backus wrote:

> Qualifying the ctor as `inout` works fine

I can see how a DConf Online presention is shaping up in your head. ;)

  http://dconf.org/2021/online/index.html

We need a collective understanding of effective use of such fundamental 
concepts.


Ali



Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 16:12:39 UTC, Paul Backus wrote:

On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote:

[...]


You have forgotten to add a member variable of type `A` to your 
`B` struct. If you add one, you will see the following error 
message:


[...]


"implicit conversions are not allowed for arguments passed to 
`ref` parameters" was the point missing to me.


Good to know, and thank yo to everyone!



Re: I do not understand copy constructors

2021-08-12 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote:


It is not clear to me why the inout generated copy constructor 
of the B structure is not able to copy the A structure.


struct A
{
int[] data;

this(ref return scope   A rhs){ /* 
body */ }
this(ref return scope const A rhs) const  { /* 
body */}
this(ref return scope immutable A rhs) immutable  { /* 
body */}

}

struct B
{
// default generated copy constructor, by section 
14.15.6.2

this(ref return scope inout(B) src) inout
{
foreach (i, ref inout field; src.tupleof) 
this.tupleof[i] = field;

}
}

Can point me to a code example of when the D generated copy 
constructor fails to copy A, and why?


You have forgotten to add a member variable of type `A` to your 
`B` struct. If you add one, you will see the following error 
message:


```
onlineapp.d(18): Error: none of the overloads of `__ctor` are 
callable using a `inout` object, candidates are:

onlineapp.d(5):`onlineapp.A.this(return ref scope A rhs)`
onlineapp.d(6):`onlineapp.A.this(return ref scope 
const(A) rhs)`
onlineapp.d(7):`onlineapp.A.this(return ref scope 
immutable(A) rhs)`

```

(Full example: https://run.dlang.io/is/9BrpZj)

Essentially, you cannot use a mutable, `const`, or `immutable` 
copy constructor to copy an `inout` object, only an `inout` copy 
constructor.


The reason for this is a bit subtle. Normally, `inout` can 
convert to `const`, so you might expect that the `const` copy 
constructor could be used to construct a copy of an `inout` 
object. However, copy constructors take their arguments by `ref`, 
and implicit conversions are not allowed for arguments passed to 
`ref` parameters. (I cannot find a citation in the spec for this, 
but you can verify it yourself.)


Here's a simplified example that gives the same error:

```d
void f(inout(int)[] a)
{
g(a);
}

void g(ref int[] a) {}
void g(ref const(int)[] a) {}
void g(ref immutable(int)[] a) {}
```


Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 15:50:05 UTC, Tejas wrote:

On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote:
On Thursday, 12 August 2021 at 14:57:16 UTC, Steven 
Schveighoffer wrote:

[...]


It is not clear to me why the inout generated copy constructor 
of the B structure is not able to copy the A structure.


[...]


Why will copy constructor of ```struct B``` accept argument of 
type ```A```?


You are right, I forgot the A member, now it is clear:

struct A
{
int[] data;

this(ref return scope   A rhs){}
this(ref return scope const A rhs) const  {}
this(ref return scope immutable A rhs) immutable  {}
}

struct B
{
// default generated copy constructor, by section 
14.15.6.2

this(ref return scope inout(B) src) inout
{
foreach (i, ref inout field; src.tupleof) 
this.tupleof[i] = field;

}
A a;
}
Error: none of the overloads of `__ctor` are callable using a 
`inout` object, candidates are:

`A.this(return ref scope A rhs)`
`A.this(return ref scope const(A) rhs)`
`A.this(return ref scope immutable(A) rhs)`

Thank you everybody.


Re: I do not understand copy constructors

2021-08-12 Thread Tejas via Digitalmars-d-learn

On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote:
On Thursday, 12 August 2021 at 14:57:16 UTC, Steven 
Schveighoffer wrote:

[...]


It is not clear to me why the inout generated copy constructor 
of the B structure is not able to copy the A structure.


[...]


Why will copy constructor of ```struct B``` accept argument of 
type ```A```?


Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn
On Thursday, 12 August 2021 at 14:57:16 UTC, Steven Schveighoffer 
wrote:

On 8/12/21 10:08 AM, Learner wrote:

On Thursday, 12 August 2021 at 13:56:17 UTC, Paul Backus wrote:

On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote:


That worked fine, but the codebase is @safe:

```d
cast from `int[]` to `inout(int[])` not allowed in safe code
```

So copy constructors force me to introduce trusted methods, 
while that was not necessary with postblits?


A postblit would simply ignore the type qualifier--which can 
lead to undefined behavior. (Scroll down to the paragraph 
that begins "An unqualified postblit..." under ["Struct 
Postblits"][1] in the spec.) The copy constructor merely 
forces you to be honest about the safety of your code.


In your case, I would recommend encapsulating the unsafe cast 
in a function like the following:


```d
T[] dupWithQualifiers(T[] array)
{
    auto copy = array.dup;
    return (() @trusted => cast(T[]) copy)();
}
```

You can then use this function in place of `dup` in your copy 
constructor.


[1]: https://dlang.org/spec/struct.html#struct-postblit


Thank you, now everything is more clear.

A last question, if you do not mind, just to better understand 
inout. It seems a shortcut to avoid repeating the same 
function body for mutable, const, and immutable. Why the 
following code is not equal to the single inout constructor?


     struct A {
     int[] data;

     //this(ref return scope inout A rhs) inout { /*body*/ 
}


     this(ref return scope   Timestamp rhs) { 
/*body*/ }
     this(ref return scope const Timestamp rhs) const 
{ /*body*/ }
     this(ref return scope immutable Timestamp rhs) 
immutable { /*body*/ }

     }
     Error: Generating an `inout` copy constructor for `struct 
B` failed, therefore instances of it are uncopyable


Inout is compatible only with inout, and not with the unrolled 
code it implies?


inout is not like a template. It's a separate qualifier that 
generates only one function (not 3 unrolled ones).


It's sort of viral like const is viral -- all underlying pieces 
have to support inout in order for you to write inout functions.


-Steve


It is not clear to me why the inout generated copy constructor of 
the B structure is not able to copy the A structure.


struct A
{
int[] data;

this(ref return scope   A rhs){ /* 
body */ }
this(ref return scope const A rhs) const  { /* 
body */}
this(ref return scope immutable A rhs) immutable  { /* 
body */}

}

struct B
{
// default generated copy constructor, by section 
14.15.6.2

this(ref return scope inout(B) src) inout
{
foreach (i, ref inout field; src.tupleof) 
this.tupleof[i] = field;

}
}

Can point me to a code example of when the D generated copy 
constructor fails to copy A, and why?







Re: I do not understand copy constructors

2021-08-12 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/12/21 10:08 AM, Learner wrote:

On Thursday, 12 August 2021 at 13:56:17 UTC, Paul Backus wrote:

On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote:


That worked fine, but the codebase is @safe:

```d
cast from `int[]` to `inout(int[])` not allowed in safe code
```

So copy constructors force me to introduce trusted methods, while 
that was not necessary with postblits?


A postblit would simply ignore the type qualifier--which can lead to 
undefined behavior. (Scroll down to the paragraph that begins "An 
unqualified postblit..." under ["Struct Postblits"][1] in the spec.) 
The copy constructor merely forces you to be honest about the safety 
of your code.


In your case, I would recommend encapsulating the unsafe cast in a 
function like the following:


```d
T[] dupWithQualifiers(T[] array)
{
    auto copy = array.dup;
    return (() @trusted => cast(T[]) copy)();
}
```

You can then use this function in place of `dup` in your copy 
constructor.


[1]: https://dlang.org/spec/struct.html#struct-postblit


Thank you, now everything is more clear.

A last question, if you do not mind, just to better understand inout. It 
seems a shortcut to avoid repeating the same function body for mutable, 
const, and immutable. Why the following code is not equal to the single 
inout constructor?


     struct A {
     int[] data;

     //this(ref return scope inout A rhs) inout { /*body*/ }

     this(ref return scope   Timestamp rhs) { /*body*/ }
     this(ref return scope const Timestamp rhs) const { /*body*/ }
     this(ref return scope immutable Timestamp rhs) immutable { 
/*body*/ }

     }
     Error: Generating an `inout` copy constructor for `struct B` 
failed, therefore instances of it are uncopyable


Inout is compatible only with inout, and not with the unrolled code it 
implies?


inout is not like a template. It's a separate qualifier that generates 
only one function (not 3 unrolled ones).


It's sort of viral like const is viral -- all underlying pieces have to 
support inout in order for you to write inout functions.


-Steve


Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 13:56:17 UTC, Paul Backus wrote:

On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote:


That worked fine, but the codebase is @safe:

```d
cast from `int[]` to `inout(int[])` not allowed in safe code
```

So copy constructors force me to introduce trusted methods, 
while that was not necessary with postblits?


A postblit would simply ignore the type qualifier--which can 
lead to undefined behavior. (Scroll down to the paragraph that 
begins "An unqualified postblit..." under ["Struct 
Postblits"][1] in the spec.) The copy constructor merely forces 
you to be honest about the safety of your code.


In your case, I would recommend encapsulating the unsafe cast 
in a function like the following:


```d
T[] dupWithQualifiers(T[] array)
{
auto copy = array.dup;
return (() @trusted => cast(T[]) copy)();
}
```

You can then use this function in place of `dup` in your copy 
constructor.


[1]: https://dlang.org/spec/struct.html#struct-postblit


Thank you, now everything is more clear.

A last question, if you do not mind, just to better understand 
inout. It seems a shortcut to avoid repeating the same function 
body for mutable, const, and immutable. Why the following code is 
not equal to the single inout constructor?


struct A {
int[] data;

//this(ref return scope inout A rhs) inout
{ /*body*/ }


this(ref return scope   Timestamp rhs)
{ /*body*/ }
this(ref return scope const Timestamp rhs) const  
{ /*body*/ }
this(ref return scope immutable Timestamp rhs) immutable  
{ /*body*/ }

}
Error: Generating an `inout` copy constructor for `struct B` 
failed, therefore instances of it are uncopyable


Inout is compatible only with inout, and not with the unrolled 
code it implies?






Re: I do not understand copy constructors

2021-08-12 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote:


That worked fine, but the codebase is @safe:

```d
cast from `int[]` to `inout(int[])` not allowed in safe code
```

So copy constructors force me to introduce trusted methods, 
while that was not necessary with postblits?


A postblit would simply ignore the type qualifier--which can lead 
to undefined behavior. (Scroll down to the paragraph that begins 
"An unqualified postblit..." under ["Struct Postblits"][1] in the 
spec.) The copy constructor merely forces you to be honest about 
the safety of your code.


In your case, I would recommend encapsulating the unsafe cast in 
a function like the following:


```d
T[] dupWithQualifiers(T[] array)
{
auto copy = array.dup;
return (() @trusted => cast(T[]) copy)();
}
```

You can then use this function in place of `dup` in your copy 
constructor.


[1]: https://dlang.org/spec/struct.html#struct-postblit


Re: I do not understand copy constructors

2021-08-12 Thread Tejas via Digitalmars-d-learn

On Thursday, 12 August 2021 at 12:28:32 UTC, Learner wrote:

On Thursday, 12 August 2021 at 12:22:22 UTC, Tejas wrote:

On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote:

[...]


Works with ```@safe``` as well

Paul was just trying to make that other answer work, you don't 
have to make copy constructors ```@trusted```


Operations are needed on `other` data, that was the reason for 
a `postblit` in the original case: an `int[]` data array needs 
to be duplicated.


Hey, this should be good enough now:
```d
import std;
struct Foo {
this(ref inout Foo other) /*inout*/ @safe{
/*foreach(i, v; other.tupleof)
this.tupleof[i] = cast(typeof(this.tupleof[i]))v;*/
a = other.a;
b = other.b;
foreach(i, elem ;other.c)
c[i] = elem;

}

@disable this(this);
int a;
float b;
double[] c;
 }

void main()@safe{
immutable Foo a;
const Foo c;
Foo b = a;//mutable b from immutable a
//writeln(typeof(b).stringof);  //Output is Foo
const Foo d = c;//const d from const c
Foo e = c;//mutable e from const c
//immutable Foo f = b;//immutable f from mutable b I 
don't know why this fails but const from mutable succeeds

const Foo g = b;//const g from mutable b
}
```


Re: I do not understand copy constructors

2021-08-12 Thread Tejas via Digitalmars-d-learn

On Thursday, 12 August 2021 at 12:22:22 UTC, Tejas wrote:

On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote:

[...]


Works with ```@safe``` as well

Paul was just trying to make that other answer work, you don't 
have to make copy constructors ```@trusted```


Ignore this,  it doesn't work for dynamic arrays(but it does for 
static, ie, fixed length arrays)




Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 12:22:22 UTC, Tejas wrote:

On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote:

[...]


Works with ```@safe``` as well

Paul was just trying to make that other answer work, you don't 
have to make copy constructors ```@trusted```


Operations are needed on `other` data, that was the reason for a 
`postblit` in the original case: an `int[]` data array needs to 
be duplicated.




Re: I do not understand copy constructors

2021-08-12 Thread Tejas via Digitalmars-d-learn

On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote:

On Thursday, 12 August 2021 at 11:54:22 UTC, Learner wrote:

[...]


Just add ```inout``` inside ```this(ref inout/*notice the 
inout*/ Foo other) inout/*notice the inout*/```


Example code:
```d
struct Foo {
this(ref inout Foo other) inout {
foreach(i, v; other.tupleof)
this.tupleof[i] = v;
}

@disable this(this);
int a;
float b;
double c;
 }

void main(){
immutable Foo a;
const Foo c;
Foo b = a;//mutable b and immutable a
const Foo d = c;//const d and const c
Foo e = c;//mutable e and const c
immutable Foo f = b;//immutable f and mutable b
const Foo g = b;//const g and mutable b
}

```


Works with ```@safe``` as well

Paul was just trying to make that other answer work, you don't 
have to make copy constructors ```@trusted```


Re: I do not understand copy constructors

2021-08-12 Thread Tejas via Digitalmars-d-learn

On Thursday, 12 August 2021 at 11:54:22 UTC, Learner wrote:
On Thursday, 12 August 2021 at 10:10:17 UTC, rikki cattermole 
wrote:


On 12/08/2021 9:36 PM, Learner wrote:
It seems that there is no easy way to transition from a 
postblit to a copy constructor, no?


struct Foo {
this(ref Foo other) {
foreach(i, v; other.tupleof)
this.tupleof[i] = v;
}

@disable this(this);
}


This results to:

Generating an `inout` copy constructor for `struct A` 
failed, therefore instances of it are uncopyable


Just add ```inout``` inside ```this(ref inout/*notice the inout*/ 
Foo other) inout/*notice the inout*/```


Example code:
```d
struct Foo {
this(ref inout Foo other) inout {
foreach(i, v; other.tupleof)
this.tupleof[i] = v;
}

@disable this(this);
int a;
float b;
double c;
 }

void main(){
immutable Foo a;
const Foo c;
Foo b = a;//mutable b and immutable a
const Foo d = c;//const d and const c
Foo e = c;//mutable e and const c
immutable Foo f = b;//immutable f and mutable b
const Foo g = b;//const g and mutable b
}

```


Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 11:32:03 UTC, Paul Backus wrote:

On Thursday, 12 August 2021 at 11:19:34 UTC, drug wrote:

```D
struct A {
int[] data;
this(ref return scope inout A rhs) /* no inout here */ { 
data = rhs.data.dup; }

}
```
The problem is that if you qualify the ctor itself then if you 
pass const/immutable rhs to it then the ctor is 
const/immutable too (like the args) and of course you cannot 
modify this, so the error.


To make a copy ctor you need to qualify copy ctor args as 
inout but the copy ctor itself shall be mutable and have no 
const,immutable or inout qualifier.


This is not true. Qualifying the ctor as `inout` works fine: 
https://run.dlang.io/is/Kpzp5M


The problem in this example is that `.dup` always returns a 
mutable array, even if the array being copied is `inout`. The 
solution is to cast the copy back to the original type:


```d
this(ref return scope inout A rhs) inout
{
data = cast(typeof(rhs.data)) rhs.data.dup;
}
```


That worked fine, but the codebase is @safe:

```d
cast from `int[]` to `inout(int[])` not allowed in safe code
```

So copy constructors force me to introduce trusted methods, while 
that was not necessary with postblits?





Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 11:07:24 UTC, drug wrote:

12.08.2021 12:36, Learner пишет:

 > It seems that there is no easy way to transition from a 
postblit to a

copy constructor, no?





You just need both const and mutable copy ctors to replace 
inout one:

```D
struct A {
int[] data;
this(ref return scope A rhs) { data = rhs.data.dup; }
this(ref return scope const A rhs) const { data = 
rhs.data.dup; }

}
```

the mutable copy ctor accepts mutable data and the const copy 
ctor accepts const and immutable data


That still fails:

Generating an `inout` copy constructor for `struct B` failed, 
therefore instances of it are uncopyable


Also if I remove the `const` body (can I assign data if the 
method is const?)


```D
struct A {
 int[] data;
 this(ref return scope A rhs) { data = rhs.data.dup; }
 this(ref return scope const A rhs) const {}
 }
Generating an `inout` copy constructor for `struct B` failed, 
therefore instances of it are uncopyable

```




Re: I do not understand copy constructors

2021-08-12 Thread drug via Digitalmars-d-learn

12.08.2021 14:32, Paul Backus пишет:


This is not true. Qualifying the ctor as `inout` works fine: 
https://run.dlang.io/is/Kpzp5M


The problem in this example is that `.dup` always returns a mutable 
array, even if the array being copied is `inout`. The solution is to 
cast the copy back to the original type:


```d
this(ref return scope inout A rhs) inout
{
     data = cast(typeof(rhs.data)) rhs.data.dup;
}
```


Yes, it's not true. I forgot that ctors are special in contrast to 
regular methods and can modify the aggregate they belong to even if the 
ctor has const/immutable/inout qualifier.


Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn
On Thursday, 12 August 2021 at 10:10:17 UTC, rikki cattermole 
wrote:


On 12/08/2021 9:36 PM, Learner wrote:
It seems that there is no easy way to transition from a 
postblit to a copy constructor, no?


struct Foo {
this(ref Foo other) {
foreach(i, v; other.tupleof)
this.tupleof[i] = v;
}

@disable this(this);
}


This results to:

Generating an `inout` copy constructor for `struct A` failed, 
therefore instances of it are uncopyable


Re: I do not understand copy constructors

2021-08-12 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 12 August 2021 at 11:19:34 UTC, drug wrote:

```D
struct A {
int[] data;
this(ref return scope inout A rhs) /* no inout here */ { 
data = rhs.data.dup; }

}
```
The problem is that if you qualify the ctor itself then if you 
pass const/immutable rhs to it then the ctor is const/immutable 
too (like the args) and of course you cannot modify this, so 
the error.


To make a copy ctor you need to qualify copy ctor args as inout 
but the copy ctor itself shall be mutable and have no 
const,immutable or inout qualifier.


This is not true. Qualifying the ctor as `inout` works fine: 
https://run.dlang.io/is/Kpzp5M


The problem in this example is that `.dup` always returns a 
mutable array, even if the array being copied is `inout`. The 
solution is to cast the copy back to the original type:


```d
this(ref return scope inout A rhs) inout
{
data = cast(typeof(rhs.data)) rhs.data.dup;
}
```


Re: I do not understand copy constructors

2021-08-12 Thread drug via Digitalmars-d-learn

12.08.2021 14:07, drug пишет:

12.08.2021 12:36, Learner пишет:


 > It seems that there is no easy way to transition from a postblit to a
copy constructor, no?





You just need both const and mutable copy ctors to replace inout one:
```D
struct A {
     int[] data;
     this(ref return scope A rhs) { data = rhs.data.dup; }
     this(ref return scope const A rhs) const { data = rhs.data.dup; }
}
```

the mutable copy ctor accepts mutable data and the const copy ctor 
accepts const and immutable data


but using inout ctor is easier:
```D
struct A {
int[] data;
this(ref return scope inout A rhs) /* no inout here */ { data = 
rhs.data.dup; }

}
```
The problem is that if you qualify the ctor itself then if you pass 
const/immutable rhs to it then the ctor is const/immutable too (like the 
args) and of course you cannot modify this, so the error.


To make a copy ctor you need to qualify copy ctor args as inout but the 
copy ctor itself shall be mutable and have no const,immutable or inout 
qualifier.


Re: I do not understand copy constructors

2021-08-12 Thread drug via Digitalmars-d-learn

12.08.2021 12:36, Learner пишет:


 > It seems that there is no easy way to transition from a postblit to a
copy constructor, no?





You just need both const and mutable copy ctors to replace inout one:
```D
struct A {
int[] data;
this(ref return scope A rhs) { data = rhs.data.dup; }
this(ref return scope const A rhs) const { data = rhs.data.dup; }
}
```

the mutable copy ctor accepts mutable data and the const copy ctor 
accepts const and immutable data


Re: I do not understand copy constructors

2021-08-12 Thread rikki cattermole via Digitalmars-d-learn



On 12/08/2021 9:36 PM, Learner wrote:
It seems that there is no easy way to transition from a postblit to a 
copy constructor, no?


struct Foo {
this(ref Foo other) {
foreach(i, v; other.tupleof)
this.tupleof[i] = v;
}

@disable this(this);
}


Re: I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

On Thursday, 12 August 2021 at 09:14:02 UTC, Paul Backus wrote:

On Thursday, 12 August 2021 at 08:42:27 UTC, Learner wrote:

struct A {
int[] data
this(ref return scope A rhs) { data = ths.data.dup; }
}

Generating an `inout` copy constructor for `struct B` 
failed, therefore instances of it are uncopyable


What is an `inout` copy constructor? What should I change in A?


When the compiler generates a copy constructor for a struct, it 
generates it with the following signature:


```d
this(ref return scope inout(typeof(this)) src) inout
```

(Source: 
https://dlang.org/spec/struct.html#implicit-copy-constructors)


Notice that both the `src` object and the object being 
constructed (`this`) are qualified with `inout`.


`inout` is a special type qualifier that allows the same 
function to be used for mutable, `const`, and `immutable` 
arguments. To make this work, the compiler imposes heavy 
restrictions on what you can do with an `inout`-qualified 
object--only operations that are valid on mutable, `const`, 
*and* `immutable` objects are allowed for `inout`.


(Source: https://dlang.org/spec/function.html#inout-functions)

`A`'s copy constructor does not have any type qualifiers on its 
`rhs` argument or its `this` reference, so both default to 
mutable. In other words: `A`'s copy constructor can only be 
used to construct a mutable copy from a mutable original 
object. It *cannot* be used to construct an `inout` copy from 
an `inout` object.


In order to make the generated copy constructor work, you need 
to give `A` a copy constructor that can copy `inout` objects. 
There are two possibilities here:


1. Make `A`'s copy constructor `inout`: `this(ref return scope 
inout A rhs) inout`
2. Make `A`'s copy constructor `const`: `this(ref return scope 
const A rhs) const`


While option 2. is not working:

struct A {
int[] data;
this(ref return scope const A rhs) const {}
}
Error: Generating an `inout` copy constructor for `struct A` 
failed, therefore instances of it are uncopyable


Option .1 actually works, with an empty body, while it fails with 
the actual body:


struct A {
int[] data;
this(ref return scope inout A rhs) inout { data = 
rhs.data.dup; }

}
Error: cannot implicitly convert expression 
`dup(cast(const(int)[])rhs.data)` of type `int[]` to 
`inout(int[])`


It seems that there is no easy way to transition from a postblit 
to a copy constructor, no?






Re: I do not understand copy constructors

2021-08-12 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 12 August 2021 at 08:42:27 UTC, Learner wrote:

struct A {
int[] data
this(ref return scope A rhs) { data = ths.data.dup; }
}

Generating an `inout` copy constructor for `struct B` 
failed, therefore instances of it are uncopyable


What is an `inout` copy constructor? What should I change in A?


When the compiler generates a copy constructor for a struct, it 
generates it with the following signature:


```d
this(ref return scope inout(typeof(this)) src) inout
```

(Source: 
https://dlang.org/spec/struct.html#implicit-copy-constructors)


Notice that both the `src` object and the object being 
constructed (`this`) are qualified with `inout`.


`inout` is a special type qualifier that allows the same function 
to be used for mutable, `const`, and `immutable` arguments. To 
make this work, the compiler imposes heavy restrictions on what 
you can do with an `inout`-qualified object--only operations that 
are valid on mutable, `const`, *and* `immutable` objects are 
allowed for `inout`.


(Source: https://dlang.org/spec/function.html#inout-functions)

`A`'s copy constructor does not have any type qualifiers on its 
`rhs` argument or its `this` reference, so both default to 
mutable. In other words: `A`'s copy constructor can only be used 
to construct a mutable copy from a mutable original object. It 
*cannot* be used to construct an `inout` copy from an `inout` 
object.


In order to make the generated copy constructor work, you need to 
give `A` a copy constructor that can copy `inout` objects. There 
are two possibilities here:


1. Make `A`'s copy constructor `inout`: `this(ref return scope 
inout A rhs) inout`
2. Make `A`'s copy constructor `const`: `this(ref return scope 
const A rhs) const`


I do not understand copy constructors

2021-08-12 Thread Learner via Digitalmars-d-learn

I have a structure like, used by other structures:

struct A {
int[] data;
this(this) { data = data.dup; }
}

I am trying to upgrade it to use copy constructor:

struct A {
int[] data
this(ref return scope A rhs) { data = ths.data.dup; }
}

Generating an `inout` copy constructor for `struct B` failed, 
therefore instances of it are uncopyable


What is an `inout` copy constructor? What should I change in A?