Re: Create alias of same name in inner scope, bug or feature?

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

On Saturday, 14 August 2021 at 04:01:31 UTC, Mike Parker wrote:

On Saturday, 14 August 2021 at 03:47:05 UTC, Tejas wrote:

```d
import std;
auto abc(T)(auto ref T a, auto ref T b){
return a+b;
}

auto def(T)(auto ref T a, auto ref T b){
return a*b;

}
alias macro_1 = abc;
void main()
{
writeln(macro_1(15, 20));
alias macro_1 = def;// is this NOT considered variable 
shadowing?

writeln(macro_1(100, 20));

}
```


Shadowing local symbols is illegal. But it's okay for local 
symbols to have the same name as module-scope symbols. You can 
disambigbuate with [the module scope operator][1]:


```d
void main()
   macro_1(); // the local symbol
   .macro_1(); // the external symbol
}
```

[1]: https://dlang.org/spec/module.html#module_scope_operators


Oh right, the ```.``` operator will reference variable in the 
_module_ scope, not just the _immediate outer scope_, that's why 
it is not considered shadowing in that case.


Thank you very much!




Re: Create alias of same name in inner scope, bug or feature?

2021-08-13 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 14 August 2021 at 03:47:05 UTC, Tejas wrote:

```d
import std;
auto abc(T)(auto ref T a, auto ref T b){
return a+b;
}

auto def(T)(auto ref T a, auto ref T b){
return a*b;

}
alias macro_1 = abc;
void main()
{
writeln(macro_1(15, 20));
alias macro_1 = def;// is this NOT considered variable 
shadowing?

writeln(macro_1(100, 20));

}
```


Shadowing local symbols is illegal. But it's okay for local 
symbols to have the same name as module-scope symbols. You can 
disambigbuate with [the module scope operator][1]:


```d
void main()
   macro_1(); // the local symbol
   .macro_1(); // the external symbol
}
```

[1]: https://dlang.org/spec/module.html#module_scope_operators


Create alias of same name in inner scope, bug or feature?

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

```d
import std;
auto abc(T)(auto ref T a, auto ref T b){
return a+b;
}

auto def(T)(auto ref T a, auto ref T b){
return a*b;

}
alias macro_1 = abc;
void main()
{
writeln(macro_1(15, 20));
alias macro_1 = def;// is this NOT considered variable 
shadowing?

writeln(macro_1(100, 20));

}
```


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

2021-08-13 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:36:35 UTC, Ruby The Roobster 
wrote:




Thank you very much.  The program runs successfully now.


You've got another potential issue you should be aware of. You've 
name a member of your `Skeleton` as `init`. This may cause issues 
at some point, as every type in D has a default `init` property, 
even structs. You shouldn't use that name in any type you define.


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

2021-08-13 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:10:38 UTC, Steven Schveighoffer 
wrote:


Well, subtracting the length doesn't do much, you aren't 
actually accessing the array block, you are just changing the 
reference (which lives in thread-local storage). I kind of feel 
like the whole entity table thing is not correct anyway. Did 
you (Mike) also comment out the `did` call? Because that looks 
more suspicious to me. What it is doing is going through all 
the entities from the removed one on and setting their id to 1 
less. HOWEVER, it's not actually *moving* the entities down in 
the array.


I suspected the `did` function first, but the issue persisted 
when I commented out the call in the destructor. I didn't know 
what to think when I found that commenting out the `.length` 
deprecation eliminated it.





I suspect there is a memory access violation or some other 
issue that's causing it to crash rather than exit normally.


It's not crashing. It's hanging.



Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Aug 13, 2021 at 04:35:54PM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 8/13/21 4:23 PM, Marcone wrote:
> 
> > string x = "Hello World!";
> > writeln(x[x.indexOf("e")..x.indexOf("r")]);
> 
> I don't see the usefulness and there are the following problems with
> it:
> 
> - Not an algorithmic complexity issue but it sounds to me like a
> pessimization to go through the elements in linear fashion, obtain
> indexes and then iterate between the indexes again.
[...]

In the above example, what all those indexOf calls really want to say
is, "give me a slice of x starting from the first occurrence of 'e' to
the next occurrence of 'r'".  Once this is understood, the rest follows:

writeln(x.find('e') // find first occurrence of 'e'
.until('r') // slice until next occurrence of 'r'
);

Or more concisely:

writeln(x.find('e').until('r'));

This iterates x only once, and also avoids the pathological case where
'r' appears before 'e', which in the original code would throw a
RangeError because it generates a slice of negative length.

//

OTOH, if the OP insists that he wants arbitrary expressions inside
[...], one way to do it is to overload opSlice and opIndex, then create
placeholder objects that abstractly refer to parts of a string that
opIndex then interprets. Something like this:

// Warning: untested code
struct Idx { dchar ch; }
struct SliceRange { size_t start, end; }

struct StringWrapper {
string impl;
alias impl this;

SliceRange opSlice(Idx i1, Idx i2) {
return SliceRange(impl.indexOf(i1.ch),
impl.indexOf(i2.ch));
// or whatever more efficient implementation you
// wish to use
}

auto opIndex(SliceRange sr) {
return StringWrapper(impl[sr.start, sr.end]);
}

// Don't forget to implement .opDollar, which I omit
// here for conciseness.
}

StringWrapper blah = "abcdefgh";
assert(blah[Idx('c') .. Idx('g')] == "cdefg");

Note that the above is incomplete; it's just a sketch of the concept. To
make it work for all cases, opSlice needs to handle if one or both of
the indices are integers, etc..  And Idx probably needs operator
overloading in order to support arbitrary expressions (it basically
amounts to an expression template or a runtime expression tree, if taken
to its logical conclusion).

Truth be told, though, this is killing an ant with a nuclear warhead.  Why not
just write `x.find('e').until('r')` instead. ;-)


T

-- 
Valentine's Day: an occasion for florists to reach into the wallets of nominal 
lovers in dire need of being reminded to profess their hypothetical love for 
their long-forgotten.


Re: How to extend the string class to return this inside the square bracket?

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

On 8/13/21 7:23 PM, Marcone wrote:

On Friday, 13 August 2021 at 23:08:07 UTC, jfondren wrote:

On Friday, 13 August 2021 at 22:09:59 UTC, Marcone wrote:


Isn't there some unario operator template that I can use with lambda 
to handle a string literal?


So, something other than an exact "lit"[0..this.xx(..)] syntax is fine?

What didn't you like about `"Hello World!".findSplit("o")[0].writeln;` 
then?


What is a real example of something you want to do?


writeln("Hello World!"[x.indexOf("e")..x.indexOf("r")]);

indexOf()is just a simple example, not the goal. I want handle literal 
inside [] like it bellow, but in literal:


string x = "Hello World!";
writeln(x[x.indexOf("e")..x.indexOf("r")]);


Operator overloading is only available to custom types (structs or 
classes), and not to arrays.


You can create a type to do what you want.

e.g.:

```d
struct SliceByIndexOf
{
   string s;
   auto opIndex(size_t[2] idxs) {
  return SliceByIndexOf(s[ idxs[0] .. idxs[1]]);
   }
   size_t[2] opSlice(size_t dim : 0)(string s1, string s2) {
  import std.string;
  return [s.indexOf(s1), s.indexOf(s2)];
   }
string toString() { return s; }
}

auto sbio(string s) { return SliceByIndexOf(s); }

void main()
{
import std.stdio;
writeln("Hello World!".sbio["e" .. "r"]); // "ello Wo"
}
```

-Steve


Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread Marcone via Digitalmars-d-learn

On Friday, 13 August 2021 at 23:21:42 UTC, Ali Çehreli wrote:

On 8/13/21 4:08 PM, jfondren wrote:

On Friday, 13 August 2021 at 22:09:59 UTC, Marcone wrote:


Isn't there some unario operator template that I can use with 
lambda to handle a string literal?


So, something other than an exact "lit"[0..this.xx(..)] syntax 
is fine?


What didn't you like about `"Hello 
World!".findSplit("o")[0].writeln;` then?


What is a real example of something you want to do?


And I started writing the following but stopped because the 
semantics are not clear. I first called it 'between' but then 
should the 'o' that was searched be a part of the output?


Should "from 'o' to 'o'" produce an empty string, should it 
include a single 'o' or should it go all the way to the next 
'o'?


What about the last line which says "from 'd' to 'a'"? Is that 
an entirely empty range or just 'd' or 'd' till the end?


I don't think the programming language can decide one way or 
the other.


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

auto inclusive(R, E)(R range, E fromNeedle, E toNeedle) {
  auto found = range.find(fromNeedle);
  return chain(found.front.only, 
found.drop(1).findSplitAfter(only(toNeedle))[0]);

}

void main() {
  const s = "Hello World!";
  auto r = s.inclusive('o', 'o');
  writeln(r);

  writeln("abcdef".inclusive('d', 'a'));
}

Ali



import std;

class None {}
// Function slice()
auto slice(T1, T2, T3 = None)(T1 conteudo, T2 inicio, T3 fim = 
T3.init) {

int start, end, startlen;
	static if (is(T2 == int)) {inicio = inicio < 0 ? conteudo.length 
+ inicio : inicio;}
	static if (is(T3 == int)) {fim = fim <= 0 ? conteudo.length + 
fim : fim;}
	static if (is(T2 == int)) {start = inicio;} else static if 
(is(T2 == string)){start = conteudo.countUntil(inicio);}
	static if (is(T2 == string)) {static if (is(T1 == 
string)){startlen = start + inicio.length + 1;} else {startlen = 
start + 1;}}
	static if (is(T3 == int)) {end = fim;} else static if (is(T3 == 
string)){end = startlen + conteudo[startlen..$].countUntil(fim);}
	static if (is(T3 == None)) {return conteudo[start];} else 
{return conteudo[start..end];}

}

void main(){
writeln("Hello World!".slice(1, 8)); // ello Wo
writeln("Hello World!".slice("e", "r")); // ello Wo
writeln("Hello World!".slice(1, "r")); // ello Wo
writeln("Hello World!".slice("e", 8)); // ello Wo
writeln("Hello World!".slice(6, -1)); // World (Same as $-1)
	writeln("Hello World!".slice(-12, -7)); // Hello (Same as $-12, 
$-7)
	writeln("Hello World!".slice("W", -1)); // World (Same as "W", 
$-1)
	writeln("Hello World!".slice(-12, " ")); // Hello (Same as $-12, 
" ")

}

Like this function, but inside []. So I can use functions to get 
index for slice.





Re: How to extend the string class to return this inside the square bracket?

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

On 8/13/21 4:23 PM, Marcone wrote:

> string x = "Hello World!";
> writeln(x[x.indexOf("e")..x.indexOf("r")]);

I don't see the usefulness and there are the following problems with it:

- Not an algorithmic complexity issue but it sounds to me like a 
pessimization to go through the elements in linear fashion, obtain 
indexes and then iterate between the indexes again.


- This approach requires random access, which only a subset of 
collections provide.


- The semantics of the second index is not clear. What is the intent 
when we say "from 'f' to 'n'" in the string "confusing"? Is it an error 
because the indexes 3..2 would be illegal? Or did we mean second 'n' in 
the string?


On the other hand, the programmer can build any semantic with the 
existing range algorithms. And that would work even with InputRanges.


You didn't ask but sorry, this feature is not for me. :)

Ali



Re: How to extend the string class to return this inside the square bracket?

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

On Friday, 13 August 2021 at 23:23:55 UTC, Marcone wrote:


writeln("Hello World!"[x.indexOf("e")..x.indexOf("r")]);

indexOf()is just a simple example, not the goal. I want handle 
literal inside [] like it bellow, but in literal:


string x = "Hello World!";
writeln(x[x.indexOf("e")..x.indexOf("r")]);


You can use the `pipe` function to bind an arbitrary expression 
to a variable:


```d
import std.functional: pipe;
import std.algorithm: countUntil;
import std.stdio: writeln;

"Hello world!"
.pipe!(s => s[s.countUntil('e') .. s.countUntil('r')])
.writeln;
```


Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread jfondren via Digitalmars-d-learn

On Friday, 13 August 2021 at 23:23:55 UTC, Marcone wrote:

On Friday, 13 August 2021 at 23:08:07 UTC, jfondren wrote:

On Friday, 13 August 2021 at 22:09:59 UTC, Marcone wrote:


Isn't there some unario operator template that I can use with 
lambda to handle a string literal?


So, something other than an exact "lit"[0..this.xx(..)] syntax 
is fine?


What didn't you like about `"Hello 
World!".findSplit("o")[0].writeln;` then?


What is a real example of something you want to do?


writeln("Hello World!"[x.indexOf("e")..x.indexOf("r")]);

indexOf()is just a simple example, not the goal. I want handle 
literal inside [] like it bellow, but in literal:


string x = "Hello World!";
writeln(x[x.indexOf("e")..x.indexOf("r")]);


```d
unittest {
import std.functional : pipe;
import std.string : indexOf;

assert("Hello, world!".pipe!(x => x[x.indexOf("e") .. 
x.indexOf("r")])

== "ello, wo");
}
```


Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread Marcone via Digitalmars-d-learn

On Friday, 13 August 2021 at 23:08:07 UTC, jfondren wrote:

On Friday, 13 August 2021 at 22:09:59 UTC, Marcone wrote:


Isn't there some unario operator template that I can use with 
lambda to handle a string literal?


So, something other than an exact "lit"[0..this.xx(..)] syntax 
is fine?


What didn't you like about `"Hello 
World!".findSplit("o")[0].writeln;` then?


What is a real example of something you want to do?


writeln("Hello World!"[x.indexOf("e")..x.indexOf("r")]);

indexOf()is just a simple example, not the goal. I want handle 
literal inside [] like it bellow, but in literal:


string x = "Hello World!";
writeln(x[x.indexOf("e")..x.indexOf("r")]);


Re: How to extend the string class to return this inside the square bracket?

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

On 8/13/21 4:08 PM, jfondren wrote:

On Friday, 13 August 2021 at 22:09:59 UTC, Marcone wrote:


Isn't there some unario operator template that I can use with lambda 
to handle a string literal?


So, something other than an exact "lit"[0..this.xx(..)] syntax is fine?

What didn't you like about `"Hello World!".findSplit("o")[0].writeln;` 
then?


What is a real example of something you want to do?


And I started writing the following but stopped because the semantics 
are not clear. I first called it 'between' but then should the 'o' that 
was searched be a part of the output?


Should "from 'o' to 'o'" produce an empty string, should it include a 
single 'o' or should it go all the way to the next 'o'?


What about the last line which says "from 'd' to 'a'"? Is that an 
entirely empty range or just 'd' or 'd' till the end?


I don't think the programming language can decide one way or the other.

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

auto inclusive(R, E)(R range, E fromNeedle, E toNeedle) {
  auto found = range.find(fromNeedle);
  return chain(found.front.only, 
found.drop(1).findSplitAfter(only(toNeedle))[0]);

}

void main() {
  const s = "Hello World!";
  auto r = s.inclusive('o', 'o');
  writeln(r);

  writeln("abcdef".inclusive('d', 'a'));
}

Ali


Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread jfondren via Digitalmars-d-learn

On Friday, 13 August 2021 at 22:09:59 UTC, Marcone wrote:


Isn't there some unario operator template that I can use with 
lambda to handle a string literal?


So, something other than an exact "lit"[0..this.xx(..)] syntax is 
fine?


What didn't you like about `"Hello 
World!".findSplit("o")[0].writeln;` then?


What is a real example of something you want to do?


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

2021-08-13 Thread Ruby The Roobster via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:10:38 UTC, Steven Schveighoffer 
wrote:

On 8/13/21 3:59 PM, Mike Parker wrote:
On Friday, 13 August 2021 at 16:18:06 UTC, Ruby The Roobster 
wrote:

...

...

...


Well, subtracting the length doesn't do much, you aren't 
actually accessing the array block, you are just changing the 
reference (which lives in thread-local storage). I kind of feel 
like the whole entity table thing is not correct anyway. Did 
you (Mike) also comment out the `did` call? Because that looks 
more suspicious to me. What it is doing is going through all 
the entities from the removed one on and setting their id to 1 
less. HOWEVER, it's not actually *moving* the entities down in 
the array.


However, you will NEVER have an entity be destroyed, because 
there is always a reference to it in the table! They will only 
get destroyed at the end, via `terminate` where things are 
destroyed deterministically.



-Steve



Okay. I removed the destructors and the 'did' function. Instead 
of those, I created a destruct(Entity op) function that works 
without causing an error.  The entitytable array is for the 
purpose of it being easier to search by id, because the index 
used to access the array is the same as the id. It's also(IMO) 
easier on my end to have every Entity object in a single array.





Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread Marcone via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:47:22 UTC, Steven Schveighoffer 
wrote:

On 8/13/21 5:05 PM, Marcone wrote:
How to extend the string class to return this inside the 
square bracket the same way opDollar $ returns the length of 
the string? Thank you.


     import std;

     void main(){
     writeln("Hello World!"[0..this.indexOf("o")]);
     }


There is no string class to extend.

`$` is a special token the compiler changes to `arr.length` for 
arrays.


-Steve


Isn't there some unario operator template that I can use with 
lambda to handle a string literal?


Re: I do not understand copy constructors

2021-08-13 Thread Paul Backus via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:34:29 UTC, Steven Schveighoffer 
wrote:
But for constructors it's not the same. Essentially because 
constructors have different rules for what they can do with 
their inputs (the inout `this` parameter can be assigned to for 
the member's first assignment).


What I was trying to say (poorly) is that inside the inout copy 
ctor, you can actually call the const `A` copy constructor with 
an input of the other `inout A`. You just can't call it on the 
member (or assign it to the member), because that would allow 
some bad things to happen in some cases.


Thanks; the special treatment of `this` is the part I was missing.

As far as I can tell there is no mention in the language spec of 
how this works. Probably worth documenting.


Re: How to extend the string class to return this inside the square bracket?

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

On 8/13/21 5:05 PM, Marcone wrote:
How to extend the string class to return this inside the square bracket 
the same way opDollar $ returns the length of the string? Thank you.


     import std;

     void main(){
     writeln("Hello World!"[0..this.indexOf("o")]);
     }


There is no string class to extend.

`$` is a special token the compiler changes to `arr.length` for arrays.

-Steve


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

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

On Friday, 13 August 2021 at 19:59:46 UTC, Mike Parker wrote:
You aren't supposed to be manipulating GC-managed memory via 
class destructors. You can not rely on that memory being valid 
at the time that it's accessed in the destructor---the object 
may already have been destroyed. Nondeterministic destruction 
is the price you pay for letting the GC manager your object 
memory.


Of course, in this case, the problem will only crop up at 
termination since the array is declared at module scope so will 
be live up until the GC shuts down. But still, not something 
you should be doing.

...


Thank you very much.  The program runs successfully now.


Re: I do not understand copy constructors

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

On 8/13/21 4:58 PM, Paul Backus wrote:

On Friday, 13 August 2021 at 15:26:15 UTC, Steven Schveighoffer wrote:
The issue is that you can't convert const (or immutable or mutable) to 
inout implicitly, and the member variable is inout inside an inout 
constructor. Therefore, there's no viable copy constructor to call for 
the member, and the outer copy constructor cannot be generated.


I'm not quite sure I follow this. Are you saying that the constructor 
call is typechecked as if it were written like this:


```d
this.field = this.field.__ctor(rhs.field);
```

...and not like this?

```d
this.field.__ctor(rhs.field);
```

Because I can see how the first version would involve an const-to-inout 
conversion, but the second version looks like it ought to work.


My point was just that `ref inout` normally binds to `ref const`.

Example:

```d
void foo(ref const int a)
{
  writeln("hi, a is ", a);
}

void bar(ref inout int b)
{
   foo(b); // fine
}
```

You implied in your statement that it was the ref-ness that prevents the 
call. Your simplified example was also a bit off, it was a double 
indirection of a ref array (which is definitely forbidden to be implicit 
cast).


But for constructors it's not the same. Essentially because constructors 
have different rules for what they can do with their inputs (the inout 
`this` parameter can be assigned to for the member's first assignment).


What I was trying to say (poorly) is that inside the inout copy ctor, 
you can actually call the const `A` copy constructor with an input of 
the other `inout A`. You just can't call it on the member (or assign it 
to the member), because that would allow some bad things to happen in 
some cases.


-Steve


Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread Marcone via Digitalmars-d-learn

On Friday, 13 August 2021 at 21:14:29 UTC, user1234 wrote:

On Friday, 13 August 2021 at 21:05:22 UTC, Marcone wrote:
How to extend the string class to return this inside the 
square bracket the same way opDollar $ returns the length of 
the string? Thank you.


import std;

void main(){
writeln("Hello World!"[0..this.indexOf("o")]);
}


this does not exist (and see few reason for) but algo + ufcs 
allows this easily, e.g


```
"Hello World!".findSplit("o")[0].writeln;
```

bonus: both can throw bound error


My example was just an example. I don't want this solution. I 
want to have the power to handle the string inside the square 
brackets.


Re: How to extend the string class to return this inside the square bracket?

2021-08-13 Thread user1234 via Digitalmars-d-learn

On Friday, 13 August 2021 at 21:05:22 UTC, Marcone wrote:
How to extend the string class to return this inside the square 
bracket the same way opDollar $ returns the length of the 
string? Thank you.


import std;

void main(){
writeln("Hello World!"[0..this.indexOf("o")]);
}


this does not exist (and see few reason for) but algo + ufcs 
allows this easily, e.g


```
"Hello World!".findSplit("o")[0].writeln;
```

bonus: both can throw bound error



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

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

On 8/13/21 3:59 PM, Mike Parker wrote:

On Friday, 13 August 2021 at 16:18:06 UTC, Ruby The Roobster wrote:

Context for this: I am creating a module of my  own, and this is a 
class contained in the module.  You will notice that after calling 
this class' constructor anywhere in a Win32 API program, that the 
program doesn't close after the window is closed.


You're hanging in `Runtime.terminate`. That's because of your `Entity` 
destructor, specifically this line:


     entitytable.length -= 1;

Comment it out and the program exits successfully.

You aren't supposed to be manipulating GC-managed memory via class 
destructors. You can not rely on that memory being valid at the time 
that it's accessed in the destructor---the object may already have been 
destroyed. Nondeterministic destruction is the price you pay for letting 
the GC manager your object memory.


Of course, in this case, the problem will only crop up at termination 
since the array is declared at module scope so will be live up until the 
GC shuts down. But still, not something you should be doing.


The runtime will help you by throwing an error if you do anything that 
directly triggers an allocation, like calling `new` or performing an 
array append. But it won't help you with anything else.


Someone more versed than I with the GC innards may be able to answer 
whether an error should be thrown here as well, or if this goes under 
the undefined behavior category.


Well, subtracting the length doesn't do much, you aren't actually 
accessing the array block, you are just changing the reference (which 
lives in thread-local storage). I kind of feel like the whole entity 
table thing is not correct anyway. Did you (Mike) also comment out the 
`did` call? Because that looks more suspicious to me. What it is doing 
is going through all the entities from the removed one on and setting 
their id to 1 less. HOWEVER, it's not actually *moving* the entities 
down in the array.


So for instance, if you have 3 entities `[e(0), e(1), e(2)]` then what 
happens when you remove e(1) is it changes their ids to `[e(0), e(0), 
e(1)]` and then resizes the array to strip off the last one, so you get 
the destroyed entity still in the table, and the one that used to be 
e(2) out of the table (though its id is set to 1 now). The result will 
be `[e(0), e(0)]`, with the second one pointing to an invalid block.


However, you will NEVER have an entity be destroyed, because there is 
always a reference to it in the table! They will only get destroyed at 
the end, via `terminate` where things are destroyed deterministically.


I think you are right that he shouldn't be changing that `entitytable` 
thing in the dtor. I also think, the memory management being used there 
is super-sketchy. Without knowing why you need to keep the table around 
in the first place, I'm unsure how it should be fixed.


I suspect there is a memory access violation or some other issue that's 
causing it to crash rather than exit normally.


-Steve


How to extend the string class to return this inside the square bracket?

2021-08-13 Thread Marcone via Digitalmars-d-learn
How to extend the string class to return this inside the square 
bracket the same way opDollar $ returns the length of the string? 
Thank you.


import std;

void main(){
writeln("Hello World!"[0..this.indexOf("o")]);
}


Re: I do not understand copy constructors

2021-08-13 Thread Paul Backus via Digitalmars-d-learn
On Friday, 13 August 2021 at 15:26:15 UTC, Steven Schveighoffer 
wrote:
The issue is that you can't convert const (or immutable or 
mutable) to inout implicitly, and the member variable is inout 
inside an inout constructor. Therefore, there's no viable copy 
constructor to call for the member, and the outer copy 
constructor cannot be generated.


I'm not quite sure I follow this. Are you saying that the 
constructor call is typechecked as if it were written like this:


```d
this.field = this.field.__ctor(rhs.field);
```

...and not like this?

```d
this.field.__ctor(rhs.field);
```

Because I can see how the first version would involve an 
const-to-inout conversion, but the second version looks like it 
ought to work.


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

2021-08-13 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 16:18:06 UTC, Ruby The Roobster 
wrote:


Context for this: I am creating a module of my  own, and this 
is a class contained in the module.  You will notice that after 
calling this class' constructor anywhere in a Win32 API 
program, that the program doesn't close after the window is 
closed.


You're hanging in `Runtime.terminate`. That's because of your 
`Entity` destructor, specifically this line:


entitytable.length -= 1;

Comment it out and the program exits successfully.

You aren't supposed to be manipulating GC-managed memory via 
class destructors. You can not rely on that memory being valid at 
the time that it's accessed in the destructor---the object may 
already have been destroyed. Nondeterministic destruction is the 
price you pay for letting the GC manager your object memory.


Of course, in this case, the problem will only crop up at 
termination since the array is declared at module scope so will 
be live up until the GC shuts down. But still, not something you 
should be doing.


The runtime will help you by throwing an error if you do anything 
that directly triggers an allocation, like calling `new` or 
performing an array append. But it won't help you with anything 
else.


Someone more versed than I with the GC innards may be able to 
answer whether an error should be thrown here as well, or if this 
goes under the undefined behavior category.


Re: Anyway to achieve the following

2021-08-13 Thread pilger via Digitalmars-d-learn

On Friday, 13 August 2021 at 19:06:17 UTC, JG wrote:
Anyway I hope it is clearer what I mean. Is it possible to do 
this in d?


union S
{
  int x;
  int a;
}

void main()
{
   S s= S(1234);

   writeln(s.a); //displays 1234
   s.x = s.x+1;
   writeln(s.a); //displays 1235
   s.a = s.a +1;
   writeln(s.a); //displays 1236
}



Re: Anyway to achieve the following

2021-08-13 Thread JG via Digitalmars-d-learn

On Friday, 13 August 2021 at 17:19:43 UTC, H. S. Teoh wrote:
On Fri, Aug 13, 2021 at 05:11:50PM +, Rekel via 
Digitalmars-d-learn wrote: [...]
For anyone more experienced with C, I'm not well known with 
references but are those semantically similar to the idea of 
using a type at a predefined location?


References are essentially pointers under the hood. The 
difference is that at the language level they are treated as 
aliases to the original variable, and are therefore guaranteed 
to be non-null.


Note that in D `ref` is not a type constructor but a storage 
qualifier, so you cannot declare a reference variable, you can 
only get one if you pass a variable to a function that takes it 
by ref.



T


Thanks for all the replies.

I had a look at emplace but it does not seem to do exactly what I 
have in mind.


What I had in mind would have the following behaviour. Suppose we 
optionally
allow "in  before the semi-colon at the end of a 
declaration. With the following semantics


T x;
T y in 

assert(x==y);
assert(==);

Note that I am not suggesting that the syntax I wrote is what 
exists or should exist. I think what I am suggesting is not the 
same as say implicitly dereferenced pointers. If you think of the 
underlying machine, variables are aliases for locations in memory 
where values are stored, and what I am asking is whether it is 
possible to alias an arbitrary location (provided it contains the 
correct type.) (I guess what I am saying is only conceptually 
true variables might end up in registers, but from the point of 
view of the language it is true since if v is a variable, then  
is defined to be its address.)


This would allow things like:

Given:

struct S
{
   int x;
   int y;
}

You can write:

S s = S(1,2) in new S;

ending up with s being defined on the heap.

Anyway I hope it is clearer what I mean. Is it possible to do 
this in d?








Re: Anyway to achieve the following

2021-08-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Aug 13, 2021 at 05:11:50PM +, Rekel via Digitalmars-d-learn wrote:
[...]
> For anyone more experienced with C, I'm not well known with references
> but are those semantically similar to the idea of using a type at a
> predefined location?

References are essentially pointers under the hood. The difference is
that at the language level they are treated as aliases to the original
variable, and are therefore guaranteed to be non-null.

Note that in D `ref` is not a type constructor but a storage qualifier,
so you cannot declare a reference variable, you can only get one if you
pass a variable to a function that takes it by ref.


T

-- 
Spaghetti code may be tangly, but lasagna code is just cheesy.


Re: Anyway to achieve the following

2021-08-13 Thread Rekel via Digitalmars-d-learn

On Friday, 13 August 2021 at 09:10:18 UTC, Tejas wrote:

On Friday, 13 August 2021 at 08:25:33 UTC, JG wrote:

Suppose one has a pointer p of type T*.
Can on declare variable a of type T which is stored in the 
location pointed to by p?

Umm is this what you want?
```d
import std.stdio;

struct S
{
  int x = 1234;
}


void main() {
S s;
/*(ref a){
 writeln(a);
 s.x = s.x + 1;
 writeln(a);
 a = a +1;
 writeln(s.x);
}(s.x);*/

auto a = &(s.x);
writeln(*a);
s.x += 1;
writeln(*a);
*a += 1;
writeln(s.x);


}
```


That's also what I thought, although at first I thought JG meant 
dereferencing a pointer to a type without reallocating the 
content.


In a way comparable to aliasing A* or having your original data 
be a union in the first place.
It seems however one can use `.` when using pointers, which is 
cool, though there seem to be some caveats: 
https://forum.dlang.org/post/hthxvxxsxdpkvwcwg...@forum.dlang.org 
(note this is 2014...))


For anyone more experienced with C, I'm not well known with 
references but are those semantically similar to the idea of 
using a type at a predefined location?


Small sidenote, this would be cool:
```d
int* ip = cast(int*)other_pointer;
int a = #a; // like a dereference but without allocating space 
for a elsewhere.

int b = #a; // Or something along those lines
a = 1;
b += 1;
assert(a==2);
```


Building a unittest executable for a dub Library

2021-08-13 Thread Rekel via Digitalmars-d-learn
I found a this thread about testing libraries: 
https://forum.dlang.org/post/mailman.1807.1522279261.3374.digitalmars-d-le...@puremagic.com


But it's very old, yet I have the same issue today.
I want to build a unittest executable for the library I've made, 
but given I'm trying to use the vscode debugger while using the 
build command in a preLaunchTask I can't just use dub test. This 
works fine for non-libraries.


After changing my targetType from 'dynamicLibrary' to automatic I 
no longer get the error, but now it's just compiling the .lib 
file.


I also tried adding an empty main but that just makes using it as 
it's supposed to more obfuscated.


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

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

On Friday, 13 August 2021 at 03:05:22 UTC, Mike Parker wrote:
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


After rewriting the program, I figured out that the bug was still 
there. Here is the function that causes it:

```d
public class Entity {
package:
ulong id;
wchar[] name;
static ulong nextid;
Point centre;
Skeleton skeleton;
public:
		this(ulong id, inout(wchar)[] name,Point centre, Skeleton 
skeleton)	{
			assert(init == true, "Error: dutils.entity has not been 
initialized yet. Call dutils.entity.initialize() to initialize 
the library.");

this.id = id;
this.name.length = name.length;
for(uint i = 0; i < name.length; i++){
this.name[i] = name[i];
}
this.nextid = this.id + 1;
this.centre = centre;
if(!skeleton.init)  {
this.skeleton = skeleton;
}
entitytable.length +=1;
entitytable[cast(uint)id] = this;
}

~this() {
entitytable.length -= 1;
this.nextid -=1;
did(cast(uint)this.id);
}

debug immutable(char)[] f() @property   {
import std.format : format;
			return format("ID: %s, Name: %s, NextID: %s, Centre: %s, 
Skeleton: %s", this.id, this.name, this.nextid, this.centre, 
this.skeleton);

}

ulong Id() @property{
return id;
}
}
```

Context for this: I am creating a module of my  own, and this is 
a class contained in the module.  You will notice that after 
calling this class' constructor anywhere in a Win32 API program, 
that the program doesn't close after the window is closed.


Here are the files:

entity.d:
```d
module dutils.entity;

debug { package import core.sys.windows.winuser; } //For 
MessageBoxA in debug messages...


public struct Skeleton  {
public Face[] faces;
package bool init = false;
public this(Face[] faces)   {
this.faces.length = faces.length;
for(uint i = 0; i < faces.length; i++)   {
this.faces[i] = faces[i];
}
}
package this(bool init) {
this.init = init;
}
public void opAssign(Skeleton rhs)  {
this.faces.length = rhs.faces.length;
for(uint i; i < rhs.faces.length; i++)   {
this.faces[i] = rhs.faces[i];
}
this.init = rhs.init;
}
}

public struct Face  {
Point[] points;
Point centre;
void opAssign(Face rhs) {
this.points.length = rhs.points.length;
for(uint i = 0; i < rhs.points.length; i++)  {
this.points[i] = rhs.points[i];
}
this.centre = rhs.centre;
}
}

public struct Point {
real x;
real y;
real z;
void opAssign(Point rhs){
this.x = rhs.x;
this.y = rhs.y;
this.z = rhs.z;
}
}

public class Entity {
package:
ulong id;
wchar[] name;
static ulong nextid;
Point centre;
Skeleton skeleton;
public:
		this(ulong id, inout(wchar)[] name,Point centre, Skeleton 
skeleton)	{
			assert(init == true, "Error: dutils.entity has not been 
initialized yet. Call dutils.entity.initialize() to initialize 
the library.");

this.id = id;
this.name.length = name.length;
for(uint i = 0; i < name.length; i++){
this.name[i] = name[i];
}
this.nextid = this.id + 1;
this.centre = centre;
if(!skeleton.init) 

Re: aliasing functions with function arguments as well ??

2021-08-13 Thread james.p.leblanc via Digitalmars-d-learn
On Friday, 13 August 2021 at 15:14:00 UTC, Steven Schveighoffer 
wrote:


There isn't a way to alias it. You can wrap it though, and hope 
the inliner takes care of the difference:


```d
auto foo(T)(T arg)
{
   static if(is(T == int)) return bar(arg, 42.33);
   else return bar(7, arg);
}
```

-Steve


Steve,

Thanks!  Yes ... this templated wrapper should be perfect for me!

Your help on my present question, as well as your continual
contributions to the forum are greatly appreciated!

Best Regards,
James




Re: I do not understand copy constructors

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

On 8/12/21 12:12 PM, Paul Backus wrote:
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.)


implicit const conversions are possible via a single ref, but not 
through a double reference. In this case, it's not the passing of the 
inout object to the const constructor.


The issue is that you can't convert const (or immutable or mutable) to 
inout implicitly, and the member variable is inout inside an inout 
constructor. Therefore, there's no viable copy constructor to call for 
the member, and the outer copy constructor cannot be generated.


As a side note, inout actually *can* bind to double references of any 
mutability, unlike const, which is a nice feature that is seldom talked 
about.


-Steve


Re: aliasing functions with function arguments as well ??

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

On 8/13/21 11:04 AM, james.p.leblanc wrote:

Dear All,

How does one use 'alias' to incorporate function arguments as well?

(I believe this is possible, from some of the examples of aliasSeq, and
the traits.Parameters documentation.  However, I was unable to come up
with anything that works.)

What should replace the question marks (???) below?


double bar( int a, double x){
  return a*x:
}



template foo(T){
  static if ( is(T==int) ){
 alias ??? = ???
  }
  else{
 alias ??? = ???
  }
}

// when T == int, I desire the aliasing to produce resulting code:
foo( int a) = bar( int a, 42.33);

// when T == double, I desire:
foo( double x) = bar( 7, x);



Thanks kindly for any information!
James

PS I am aware of the "struct holding a function allowing multiple 
dispatch concept"
... while that would fit quite okay here in my simple example, it isn't 
appropriate

for my real use.



There isn't a way to alias it. You can wrap it though, and hope the 
inliner takes care of the difference:


```d
auto foo(T)(T arg)
{
   static if(is(T == int)) return bar(arg, 42.33);
   else return bar(7, arg);
}
```

-Steve


aliasing functions with function arguments as well ??

2021-08-13 Thread james.p.leblanc via Digitalmars-d-learn

Dear All,

How does one use 'alias' to incorporate function arguments as 
well?


(I believe this is possible, from some of the examples of 
aliasSeq, and
the traits.Parameters documentation.  However, I was unable to 
come up

with anything that works.)

What should replace the question marks (???) below?


double bar( int a, double x){
  return a*x:
}



template foo(T){
  static if ( is(T==int) ){
 alias ??? = ???
  }
  else{
 alias ??? = ???
  }
}

// when T == int, I desire the aliasing to produce resulting 
code:

foo( int a) = bar( int a, 42.33);

// when T == double, I desire:
foo( double x) = bar( 7, x);



Thanks kindly for any information!
James

PS I am aware of the "struct holding a function allowing multiple 
dispatch concept"
... while that would fit quite okay here in my simple example, it 
isn't appropriate

for my real use.



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

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

On Friday, 13 August 2021 at 03:05:22 UTC, Mike Parker wrote:
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


Nevermind. I am just redoing the LRESULT function. Seems to work 
now.


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

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

On Friday, 13 August 2021 at 03:05:22 UTC, Mike Parker wrote:
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


So I edited the message loop:
```d
while((b = GetMessage(,hwnd,0,0)) != 0) {
if(exit || b == -1) {
return msg.wParam;
}
TranslateMessage();
DispatchMessage();
}
```
And some of the WndProc:
```d
extern(Windows)
LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wparam, 
LPARAM lparam) nothrow	{

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

It still produces the same result(the program never exits), so it 
doesn't look like GetMessage() is returning -1...


Re: Anyway to achieve the following

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

On Friday, 13 August 2021 at 09:30:25 UTC, Ali Çehreli wrote:
(core.lifetime is not on dlang.org at the moment for me but it 
is under /usr/include/dmd/druntime/import/core on my computer.)


It's also on dpldocs.info:

https://dpldocs.info/experimental-docs/core.lifetime.html


Re: Anyway to achieve the following

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

On 8/13/21 1:25 AM, JG wrote:

> Suppose one has a pointer p of type T*.
> Can on declare variable a of type T which is stored in the location
> pointed to by p?

You may be looking for core.lifetime.emplace. (core.lifetime is not on 
dlang.org at the moment for me but it is under 
/usr/include/dmd/druntime/import/core on my computer.)


I have some content about 'emplace' but it is not in std.conv anymore:

  http://ddili.org/ders/d.en/memory.html#ix_memory.construction,%20emplace

Ali



Re: Anyway to achieve the following

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

On Friday, 13 August 2021 at 08:25:33 UTC, JG wrote:

Suppose one has a pointer p of type T*.
Can on declare variable a of type T which is stored in the 
location pointed to by p?


As an example if we have:

struct S
{
  int x = 1234;
}

void main() {
   S s;
   //unknown construction of a using &(s.x)
   writeln(a); //displays 1234
   s.x = s.x+1;
   writeln(a); //displays 1235
   a = a +1;
   writeln(s.x); //displays 1236
}

Similar behavior can be achieved in the body of the lambda here

import std.stdio;

struct S
{
  int x = 1234;
}


void main() {
S s;
(ref a){
 writeln(a);
 s.x = s.x + 1;
 writeln(a);
 a = a +1;
 writeln(s.x);
}(s.x);
}


Umm is this what you want?
```d
import std.stdio;

struct S
{
  int x = 1234;
}


void main() {
S s;
/*(ref a){
 writeln(a);
 s.x = s.x + 1;
 writeln(a);
 a = a +1;
 writeln(s.x);
}(s.x);*/

auto a = &(s.x);
writeln(*a);
s.x += 1;
writeln(*a);
*a += 1;
writeln(s.x);


}
```


Anyway to achieve the following

2021-08-13 Thread JG via Digitalmars-d-learn

Suppose one has a pointer p of type T*.
Can on declare variable a of type T which is stored in the 
location pointed to by p?


As an example if we have:

struct S
{
  int x = 1234;
}

void main() {
   S s;
   //unknown construction of a using &(s.x)
   writeln(a); //displays 1234
   s.x = s.x+1;
   writeln(a); //displays 1235
   a = a +1;
   writeln(s.x); //displays 1236
}

Similar behavior can be achieved in the body of the lambda here

import std.stdio;

struct S
{
  int x = 1234;
}


void main() {
S s;
(ref a){
 writeln(a);
 s.x = s.x + 1;
 writeln(a);
 a = a +1;
 writeln(s.x);
}(s.x);
}