Why dtor are not executed when removing a struct from associative arrays?

2021-09-20 Thread Learner via Digitalmars-d-learn

I was expecting something like going out of scope for that

```(D)
import std.stdio;

struct S
{
~this()
{
writeln("S is being destructed");
}
}

void main()
{
S[int] aa;
aa[1] = S();
aa.remove(1);
writeln("Why no dtor call on remove?");
}

I was expecting S instance dtor called
S is being destructed
```



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 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 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 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 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 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 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?






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?



Re: variant visit not pure?

2020-05-07 Thread learner via Digitalmars-d-learn
On Thursday, 7 May 2020 at 14:53:10 UTC, Steven Schveighoffer 
wrote:

On 5/7/20 5:22 AM, learner wrote:

[...]


Because VariantN (the base of Algebraic) can literally hold 
anything, it cannot be pure, @safe, nothrow, @nogc.


As others have recommended, I suggest using TaggedAlgebraic. I 
recently have been using it to create an algebraic type to hold 
a MYSQL value, so I can migrate the mysql-native library to be 
@safe (mysql-native currently uses Variant for everything).


I added a special UDA to TaggedAlgebraic, so you can guarantee 
only @safe calls are allowed (for instance, if it can hold a 
pointer and an int, then opBinary!"+" can be marked as @safe if 
the operation fails when it's a pointer).


TaggedAlgebraic could probably do the same for pure, but not 
sure about nothrow and @nogc, since it uses exceptions when 
things aren't valid.


-Steve


Modules of D standard library aren't in a good shape, if everyone 
suggests alternatives for a basic building block as variant.


The types VariantN can hold are known at compile time, why can't 
it be specialized?





Re: variant visit not pure?

2020-05-07 Thread learner via Digitalmars-d-learn

On Thursday, 7 May 2020 at 10:41:01 UTC, Simen Kjærås wrote:

On Thursday, 7 May 2020 at 09:22:28 UTC, learner wrote:

Good morning,

Is there a reason why std.variant.visit is not inferring pure?

```
void test() pure {
Algebraic!(int, string) alg;
visit!( (string) => 0, (int) => 0)(alg);
}

Error: pure function test cannot call impure function 
test.visit!(VariantN!(16LU, int, string)).visit

```


std.variant.Algebraic is essentially a std.variant.Variant in 
different clothes. Variant is very flexible, and this comes at 
a cost (and isn't used in Algebraic, meaning you pay for things 
you don't use). Like Dukc said, you might be better off with 
Taggedalgebraic or SumType 
(https://code.dlang.org/packages/sumtype).



Variant uses runtime type information to hold *any* type. Since 
Algebraic specifically only holds a few types, all the 
framework that's in place for Variant is wasted on Algebraic, 
and makes it less useful and less performant.


--
  Simen


Thank you Simon and Dukc,

I've find this: https://issues.dlang.org/show_bug.cgi?id=16662

So, it seems that Phobos isn't in a good shape ... what a pity!


variant visit not pure?

2020-05-07 Thread learner via Digitalmars-d-learn

Good morning,

Is there a reason why std.variant.visit is not inferring pure?

```
void test() pure {
Algebraic!(int, string) alg;
visit!( (string) => 0, (int) => 0)(alg);
}

Error: pure function test cannot call impure function 
test.visit!(VariantN!(16LU, int, string)).visit

```

Thank you


Re: Retrieve the return type of the current function

2020-05-06 Thread learner via Digitalmars-d-learn

On Wednesday, 6 May 2020 at 08:04:16 UTC, Jacob Carlborg wrote:

On 2020-05-05 19:11, learner wrote:

On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:


typeof(return)


Thank you, that was indeed easy!

Is it possible to retrieve also the caller return type? 
Something like:


Yes, kind of:

void foo(string caller = __FUNCTION__)()
{
import std.traits : ReturnType;

alias R = ReturnType!(mixin(caller));
static assert(is(R == int));
}

int bar()
{
foo();
return 0;
}


Awesome and beautiful, thank you!




Re: std.uni, std.ascii, std.encoding, std.utf ugh!

2020-05-06 Thread learner via Digitalmars-d-learn

On Tuesday, 5 May 2020 at 19:24:41 UTC, WebFreak001 wrote:

On Tuesday, 5 May 2020 at 18:41:50 UTC, learner wrote:

Good morning,

Trying to do this:

```
bool foo(string s) nothrow { return s.all!isDigit; }
```

I realised that the conversion from char to dchar could throw.

I need to validate and operate over ascii strings and utf8 
strings, possibly in separate functions, what's the best way 
to transition between:


```
immutable(ubyte)[] -> validate utf8 -> string -> nothrow usage 
-> isDigit etc
immutable(ubyte)[] -> validate ascii -> AsciiString? -> 
nothrow usage -> isDigit etc
string -> validate ascii -> AsciiString? -> 
nothrow usage -> isDigit etc

```

Thank you


Thank you WebFreak,



if you want nothrow operations on the sequence of characters 
(bytes) of the strings, use `str.representation` to get 
`immutable(ubyte)[]` and work on that. This is useful for 
example for doing indexOf (countUntil), startsWith, endsWith, 
etc. Make sure at least one of your inputs is validated though 
to avoid potentially handling or cutting off unfinished code 
points. I think this is the best way to go if you want to do 
simple things.


What I really want is a way to validate an immutable(ubyte)[] 
sequence for UFT8 or ASCII, and from that point forward, apply 
functions like isDigit in nothrow functions.


If your algorithm is sufficiently complex that you would like 
to still decode but not crash, you can also manually call 
.decode with UseReplacementDchar.yes to make it emit \uFFFD for 
invalid characters.


I will simply reject invalid UTF8 input, that's coming from I/O

To get the best of both worlds, use `.byUTF!dchar` which gives 
you an input range to iterate over and defaults to using 
replacement dchar. You can then call the various algorithm & 
array functions on it.


Can you explain better?

Unless you are working with different encodings than UTF-8 
(like doing file or network operations) you shouldn't be 
needing std.encoding.


I'm expecting UTF8 and ASCII encoding from I/O

Thank you!




std.uni, std.ascii, std.encoding, std.utf ugh!

2020-05-05 Thread learner via Digitalmars-d-learn

Good morning,

Trying to do this:

```
bool foo(string s) nothrow { return s.all!isDigit; }
```

I realised that the conversion from char to dchar could throw.

I need to validate and operate over ascii strings and utf8 
strings, possibly in separate functions, what's the best way to 
transition between:


```
immutable(ubyte)[] -> validate utf8 -> string -> nothrow usage -> 
isDigit etc
immutable(ubyte)[] -> validate ascii -> AsciiString? -> nothrow 
usage -> isDigit etc
string -> validate ascii -> AsciiString? -> nothrow 
usage -> isDigit etc

```

Thank you




Re: Retrieve the return type of the current function

2020-05-05 Thread learner via Digitalmars-d-learn

On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:


typeof(return)


Thank you, that was indeed easy!

Is it possible to retrieve also the caller return type? Something 
like:


```
int foo() {
return magic();
}

auto magic(maybesomedefaulttemplateargs = ??)() {
alias R = __traits(???); // --> int!
}
```

Mixin templates maybe?


Retrieve the return type of the current function

2020-05-05 Thread learner via Digitalmars-d-learn

Good morning,

Is it possible something like this?

```
int foo() {

__traits(some_trait, some_generic_this) theInt = 0;
```

I mean, without using the function name in the body, like 
ReturnType!foo ?




How define such scheleton classes

2016-07-15 Thread Learner via Digitalmars-d-learn

abstract class AbstractObject(S)
if (IsSomeString!S)
{
}

class OtherObject(S, bool R) : AbstractObject!S
{
int x;
void Foo(int a, int b)
{
x = a + b;
static if (R)  // error
{
   // more codes .
}
}
}

class OtherObjects(S) : AbstractObject!S
{
OtherObject!(S, bool) a, b;   // error

a = new OtherObject!(S, true)();
b = new OtherObject!(S, false)();
}



Re: get number of columns and rows in an ndarray.

2016-06-15 Thread learner via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 21:54:22 UTC, Seb wrote:

On Wednesday, 15 June 2016 at 21:51:25 UTC, learner wrote:

Hi,

How can i get the number of cols and rows in and ndarray that 
has already been created?


learner


how about `shape`?

http://dlang.org/phobos/std_experimental_ndslice_slice.html#.Slice.shape


Thanks


get number of columns and rows in an ndarray.

2016-06-15 Thread learner via Digitalmars-d-learn

Hi,

How can i get the number of cols and rows in and ndarray that has 
already been created?


learner




Re: How can convert the folowing to D.

2016-04-01 Thread learner via Digitalmars-d-learn

On Friday, 1 April 2016 at 01:09:32 UTC, Ali Çehreli wrote:

On 03/31/2016 05:34 PM, learner wrote:

Hi,

I have the following code in C++.

rectangles.erase(rectangles.begin() + index);

where rectangles is:
std::vector rectangles;

how can I do something similar in D.

Learner.



import std.stdio;

void main() {
int[] a = [ 1, 2, 3, 4, 5 ];
writefln("Before: %s", a);
size_t index = 2;
a = a[index .. $];   // <-- HERE
writefln("After : %s", a);
}

Note that it's a cheap operation; the elements are still in 
memory and not destroyed. If you want to run their destructors 
you can call destroy() explicitly:


import std.stdio;
import std.algorithm;
import std.range;

struct Rect {
int i;

~this() {
writefln("Destroying %s", i);
}
}

void main() {
Rect[] a = iota(5).map!(i => Rect(i)).array;

writefln("Before: %s", a);

size_t index = 2;

// If you need to run the destructors now:
a[0 .. index].each!((ref e) => e.destroy);

a = a[index .. $];

writefln("After : %s", a);
}

Prints

Destroying 0
Destroying 1
Destroying 2
Destroying 3
Destroying 4
Before: [Rect(0), Rect(1), Rect(2), Rect(3), Rect(4)]
Destroying 0
Destroying 1
After : [Rect(2), Rect(3), Rect(4)]

Ali


thanks


How can convert the folowing to D.

2016-03-31 Thread learner via Digitalmars-d-learn

Hi,

I have the following code in C++.

rectangles.erase(rectangles.begin() + index);

where rectangles is:
std::vector rectangles;

how can I do something similar in D.

Learner.