Re: DMD [-O flag] vs. [memory allocation in a synchronized class]

2017-06-09 Thread realhet via Digitalmars-d-learn

On Thursday, 8 June 2017 at 17:39:41 UTC, Ivan Kazmenko wrote:

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


Thank You!




Out of memory error (even when using destroy())

2017-05-26 Thread realhet via Digitalmars-d-learn

Hi,

I'm kinda new to the D language and I love it already. :D So far 
I haven't got any serious problems but this one seems like beyond 
me.


import std.stdio;
void main(){
foreach(i; 0..2000){
writeln(i);
auto st = new ubyte[500_000_000];
destroy(st); //<-this doesnt matter
}
}

Compiled with DMD 2.074.0 Win32 it produces the following output:
0
1
2
core.exception.OutOfMemoryError@src\core\exception.d(696): Memory 
allocation failed


It doesn't matter that I call destroy() or not. This is ok 
because as I learned: destroy only calls the destructor and marks 
the memory block as unused.


But I also learned that GC will start to collect when it run out 
of memory but in this time the following happens:
3x half GB of allocations and deallocations, and on the 4th the 
system runs out of the 2GB
 limit which is ok. At this point the GC already has 1.5GB of 
free memory but instead of using that, it returns a Memory Error. 
Why?


Note: This is not a problem when I use smaller blocks (like 50MB).
But I want to use large blocks, without making a slow wrapper 
that emulates a large block by using smaller GC allocated blocks.


Is there a solution to this?

Thank You!


Re: Out of memory error (even when using destroy())

2017-05-26 Thread realhet via Digitalmars-d-learn

Thanks for the answer!

But hey, the GC knows that is should not search for any pointers 
in those large blocks.
And the buffer is full of 0-s at the start, so there can't be any 
'false pointers' in it. And I think the GC will not search in it 
either.


The only reference to the buffer is 'st' which will die shortly 
after it has been allocated.


64bit is not a solution because I need to produce a 32bit dll, 
and I also wanna use 32bit asm objs.
The total 2GB amount of memory is more than enough for the 
problem.
My program have to produce 300..500 MB of continuous data 
frequently. This works in MSVC32, but with D's GC it starts to 
eat memory and fails at the 4th iteration. Actually it never 
releases the previous blocks even I say so with destroy().


At this point I only can think of:
a) Work with the D allocator but emulate large blocks by 
virtually stitching small blocks together. (this is unnecessary 
complexity)
b) Allocating memory by Win32 api and not using D goodies anymore 
(also unnecessary complexity)


But these are ugly workarounds. :S

I also tried to allocate smaller blocks than the previous one, so 
it would easily fit to the prevouisly released space, and yet it 
keeps eating memory:


void alloc_dealloc(size_t siz){
auto st = new ubyte[siz];
}

void main(){
foreach(i; 0..4) alloc_dealloc(500_000_000 - 50_000_000*i);
}


Re: Out of memory error (even when using destroy())

2017-05-26 Thread realhet via Digitalmars-d-learn

Jordan Wilson wrote:
This I think achieves the spirit of your code, but without the 
memory exception:

ubyte[] st;
foreach(i; 0..2000){
writeln(i);
st.length=500_000_000; // auto = new ubyte[500_000_000];
st.length=0; // destory(st)
st.assumeSafeAppend;
// prevent allocation by assuming it's ok to overrwrite what's 
currently in st

}


Yea, that's the perfect solution. It uses exactly the amount of 
memory that is required and still I'm using D things only.
The only difference is that I need only one variable outside of 
the loop, but it's well worth it because I only need one large 
buffer at a time.
Also refreshed my knowledge about assumeSafeAppend() which is now 
clear to me, thanks to You.


Using this information I'll be able to do a BigArray class that 
will hold large amount of data without worrying that the program 
uses 3x more memory than needed :D


Thanks for everyone,
Such a helping community you have here!


Re: DMD [-O flag] vs. [memory allocation in a synchronized class]

2017-06-08 Thread realhet via Digitalmars-d-learn

On Thursday, 8 June 2017 at 10:48:41 UTC, ketmar wrote:

worksforme with -O, and with -O -inline.


I forgot to mention, that I'm generating win32 output.
DMD32 D Compiler v2.074.0


DMD [-O flag] vs. [memory allocation in a synchronized class]

2017-06-08 Thread realhet via Digitalmars-d-learn

Hi,

This code works well with the unoptimized compilation with DMD.

import std.array;

synchronized class Obj{
  private int[] arr;
  void trigger(){ arr.length += 1; }
}

void main(){
  auto k = new shared Obj;
  k.trigger;
}

And when I use the -O option, it shows the following error in the 
trigger() method:


core.exception.InvalidMemoryOperationError@src\core\exception.d(696): Invalid 
memory operation

Why? o.O


Re: DMD [-O flag] vs. [memory allocation in a synchronized class]

2017-06-08 Thread realhet via Digitalmars-d-learn

I've managed to narrow the problem even more:

//win32 dmd -O

class Obj{
  synchronized void trigger(){ new ubyte[1]; }
}

void main(){
  auto k = new shared Obj;
  k.trigger;
}

This time I got a more sophisticated error message:

object.Error@(0): Access Violation

0x7272456D in SymInitialize
0x00402667
0x00402A97
0x00402998
0x004022A0
0x76F13744 in BaseThreadInitThunk
0x773B9E54 in RtlSetCurrentTransaction
0x773B9E1F in RtlSetCurrentTransaction


Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-08 Thread realhet via Digitalmars-d-learn

On Friday, 8 June 2018 at 02:44:13 UTC, Mike Parker wrote:

...you can get it with this:

dmd -m64 -L/SUBSYSTEM:console -L/ENTRY:WinMainCRTStartup foo.d


Thank You! It works with LDC -m64 as well.
And now that I repaired my VCRedist2015 the bat file test (my 
second code example) is working too.


Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-08 Thread realhet via Digitalmars-d-learn

On Friday, 8 June 2018 at 03:08:21 UTC, Mike Franklin wrote:
I recall similar issues with a project I was working on, but I 
don't remember all the details now.  Anyway, I ended up with 
this in the end.


Using main() instead of WinMain() did the trick too. Also it's 
simpler, so I choose this way. But it was also important to learn 
about the SUBSYSTEM and ENTRY linker options.


Thank you all very much!


Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread realhet via Digitalmars-d-learn

Hi,

The following narrow test program works fine when compiled with 
DMD to 32bit target:


import std.stdio, core.sys.windows.windows, core.runtime;
extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
hPrevInstance, LPSTR lpCmdLine, int iCmdShow)

{
Runtime.initialize;
writeln("Hello");
stdout.flush; //exception
readln; //exception
return 0;
}

It shows the console window and waits for user input at readln.

If I try to compile this to 64bit target or with LDC (both 32 and 
64) it gets privileged instruction exception at stdout.flush. If 
I comment out flush then it fails at readln.


Is there a way to fix this? I don't wanna lose the console window 
even on 64bit.


Thanks!



Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread realhet via Digitalmars-d-learn
On Thursday, 7 June 2018 at 19:42:05 UTC, Steven Schveighoffer 
wrote:
Are you just compiling the 32-bit dmd version with default 
flags?
Yes, no flags at all and it defaults to a 32bit target. I can use 
the console and able to make windows, and able to setup an opengl 
window too.
The console (stdin/stdout/SetConsoleAttribute) stuff crashes only 
when I compile to 64bit with DMD or to 32/64 with LDC.


If so, it's likely an issue with MSVC runtime library not being 
properly set up. DMD 32 bit by default uses DMC runtime.
I just tried to put up msvcrt2017 runtime but doesnt solved the 
issue.


To verify, use the switch -m32mscoff to do 32-bit result but 
link against MSVC library.
Compiling this way is impossible: It can't link even basic stuff 
like GetDC().



I know this isn't really an answer, but it at least narrows it
down. Been a while since I did windows development, but it 
sounds like you are trying to print to or read from a console 
that isn't open. A windows program that has gui-only flag 
doesn't by default allocate a console. Most likely dmc just 
does it for you.


To be honest I don't use gui-only flag as I don't even know about 
where to put it :D (.def file maybe, but I don't). I use 
core.Runtime.initialize only. That is enough in 32bit but not in 
64bit.


My goal is to have a fully functional exe that contains every 
necessary things inside it. So far this is given when I use DMD 
and compile to win32.
The error I'm getting is not a 'friendly' exception. It is a 
privileged instruction crash.
And it caused only by adding the -m64 option, not changing 
anything else. The linking is done by DMD itself also. (If I link 
with msvcenv.bat && MSLink.exe, it produces also the same fail.)


Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread realhet via Digitalmars-d-learn
On Thursday, 7 June 2018 at 23:25:45 UTC, Steven Schveighoffer 
wrote:

...


The WinMain exported function works alone well and on 32bit it 
also does the console.
On 64 I also tried AllocConsole, but fail. I get the Console 
handle with GetConsoleHandle, it sends back a nonzero value.


But as I play with it, now I can broke it even when I only use 
main() as export.


This bat file runs(dmd and visual-d installed to default c:\d 
path) (It only affects LDC & win64)


echo void main(){ import std.stdio; writeln(123); } > test.d
ldmd2 -vcolumns -c -op -allinst -w -m64 -release -O -inline 
-boundscheck=off test.d

call msvcenv amd64
cd c:\d
link /LIBPATH:C:\d\ldc2\lib64 /OUT:test.exe /MACHINE:X64 /MAP 
legacy_stdio_definitions.lib test.obj druntime-ldc.lib 
phobos2-ldc.lib msvcrt.lib

test.exe


And when I want to run the same exe from outside with 
totalcommander, it brings up an "application was unable to start: 
0xc0fb exception in a small window o.O.


UPDATE: The exe only starts when "msvcenv.bat amd64" was called 
before. That enironment setter bat file is needed for the exe as 
well o.O


I really thank you for trying to help me. Maybe that other 
different runtime you mentioned is using environment variables to 
be able to start up. Tomorrow I will test it.


Re: DMD Windows 64bit target - how to setup the environment?

2017-12-29 Thread realhet via Digitalmars-d-learn
Thank You for fast help! I just reply late because I wanted to 
try out many things.


With Benjamin's list it was indeed easy to set up the environment.
I also installed LDC and it worked without problems too.
Made some tests about sse vectorization and it turned out that 
I'm in love with LDC now :D
( 
https://realhet.wordpress.com/2017/12/29/my-first-impressions-of-64-bit-dlang-compilers/ )


The next thing I wanna test is compiling speed.
As you said, DMD is fast enought to let it just compile all the 
project in one run, because it reuses a lot of data it discovered 
through the compiling process.
However I had a lot of experiences with Delphi which is a really 
fast one (at least on 32bits, without sse vectorization), and on 
top of that is uses incremental compilation. Later I got to 
Qt+MSVC, and noticed that my 40K LOC not-so-big project takes 40 
seconds to compile and another 10 to launch in the debugger. At 
the time when the program started, I already forgot why I started 
it to debug, lol. So that's why I was happy to find D, an elegant 
language that compiles fast, (not as fast as Delphi, 'though, but 
it is really comparable to it). So for development, I made a 
small incremental build manager thingie: It launches a DMD for 
each of the modules, that aren't in its cache. For a 6K LOC, 
220KB project i was able to test, it works well: When I modify a 
only high level module, it only takes 3 seconds to launch, not 7 
while I build it once with DMD. When the object cache is empty, 
it takes 6 seconds on all 8 cores, but it has to be done only 
once. On Delphi I had usually 0.5sec launch times when I changed 
only a few units, so if I have to choose 7 secs of 3 secs, then 
it's not even a question.


Anyways,
Thank You for help again!


DMD Windows 64bit target - how to setup the environment?

2017-12-25 Thread realhet via Digitalmars-d-learn

Hello,

I'm very well satisfied with the DMD 32bit compiler and the 
OptLink linker on Windows. I even made an incremental builder to 
it, and I can see the running program in 1 second.
Lately I sadly noticed, that the OptLink works only for 32bit 
target, and I need to go to 64bit if I want to have access to the 
SIMD instructions on vector operations.

So this is what I've tried so far:

- Installed visual C++ 2010.
- Installed Windows SDK 7.1 (don't know why, 'though)

  -> Error: dmd cant find "\bin\link.exe"
- Added environment variable: set VCINSTALLDIR=c:\Program Files 
(x86)\Microsoft Visual Studio 10.0\VC


  -> Error: Can't load mspdb100.dll
- Added set PATH=%PATH%;c:\Program Files (x86)\Microsoft Visual 
Studio 10.0\Common7\IDE


  -> Error: LNK1104: cannot open file 'libcmt.lib'
- copied it to c:\D\dmd2\windows\lib64 (yes, I really desperately 
want it to work lol)


  -> Error: LNK1104: OLDNAMES.lib, shell32.lib
- copied these too

And finally got the error:
  -> libcmt.lib(fdopen.obj) : fatal error LNK1112: module machine 
type 'X86' conflicts with target machine type 'x64'


So I've searched through the whole C drive and this 32bit one was 
the only libcmt.lib.
The linker is located at: "c:\Program Files (x86)\Microsoft 
Visual Studio 10.0\VC\bin\link.exe"

There is no amd64 folder near to it at all.

Obviously I'm doing something wrong because a trivial task like 
changing target to 64bit can't be so complicated. Please help and 
tell me how to do it properly!


Thanks in advance!




Re: DMD Windows 64bit target - how to setup the environment?

2017-12-25 Thread realhet via Digitalmars-d-learn
Now I have my first DMD 64bit windows console app running. (And 
I'm already afraid of the upcoming windowed application haha)


After further fiddling I installed the >>>Visual Cpp tools 
2015<<< package that contains a linker with x64 stuff in it 
(along with several GB of bloatware).


contents of test64bit.d: import std.stdio; void 
main(){writeln("Hello 64");}


compiling:

dmd test64bit.d -c -op -allinst -vcolumns -m64


linking:
"c:\Program Files (x86)\Microsoft Visual Studio 
14.0\VC\bin\amd64\link.exe"

  /MACHINE:X64
  /SUBSYSTEM:CONSOLE
  test64bit.obj
  /LIBPATH:c:\D\dmd2\windows\lib64
  /LIBPATH:"c:\Program Files (x86)\Microsoft Visual Studio 
14.0\VC\lib\amd64"
  /LIBPATH:"c:\Program Files (x86)\Windows 
Kits\8.1\Lib\winv6.3\um\x64"
  /LIBPATH:"c:\Program Files (x86)\Windows 
Kits\10\Lib\10.0.10240.0\ucrt\x64"

  legacy_stdio_definitions.lib

(note: legacy_stdio_definitions.lib contains sprintf and sscanf)


append uninitialized elements to array

2018-07-30 Thread realhet via Digitalmars-d-learn

Hello,

I've already found out how to create an array with uninitialized 
elements, but what I'm looking for is a way to append 16 
uninitialized ushorts to it and after I will it directly from 2 
SSE registers.


The approximate array length is known at the start so I could be 
able to do this by making an uninitializedArray and then doing 
the appending manually, but I wonder if there is a way to do this 
with array.reserve().


Basically it would be a thing that when this special 
uninitialized append is happening and when the reserved array 
size is big enough, it only increments the internal array length 
effectively.


Thanks


Re: append uninitialized elements to array

2018-07-31 Thread realhet via Digitalmars-d-learn

Thank You!


Re: strip() and formattedRead()

2018-03-21 Thread realhet via Digitalmars-d-learn

On Wednesday, 21 March 2018 at 18:50:18 UTC, Adam D. Ruppe wrote:

On Wednesday, 21 March 2018 at 18:44:12 UTC, realhet wrote:
Compiling this I get an error: "formattedRead: cannot deduce 
arguments from (string, string, float, float, float)"


What compiler version are you using? The newest versions allow 
this code, though the old ones require an intermediate variable 
to satisfy the `ref` requirement on formattedRead (it will want 
to update that variable to advance it past the characters it 
read).


so either update your version, or just give an and use an 
intermediate:


string s = "".strip;
formattedRead(s, )


Thank both of You! You guys are super helpful. (I'm learning from 
Ali's book and after these instant answers I was like: "I'm not 
worthy" :D)


So I had v2077.1 previously, now I've installed 2079.0 and it all 
works great.





strip() and formattedRead()

2018-03-21 Thread realhet via Digitalmars-d-learn

Hi,

I just got this problem and since an hour can't find answer to it.

  float x,y,z;
  if(formattedRead("vertex -5.1 2.4 3.666".strip, "vertex %f 
%f %f", x, y, z)){

writefln("v(%f, %f, %f)", x, y, z);
  }

Compiling this I get an error: "formattedRead: cannot deduce 
arguments from (string, string, float, float, float)"


When I don't use .strip(), just a string literal or a string 
variable it works good.


(It fails also when I'm using UFCS)

What did I do wrong?


Problem with opBinary

2018-11-14 Thread realhet via Digitalmars-d-learn

Hi,

Just a little weird thing I noticed and don't know why it is:

I have a FilePath struct and I wanted to make it work with the 
"~" operator and an additional string.


So I've created a global funct:

  FilePath opBinary(string op:"~")(FilePath p1, string p2){
return FilePath(p1, p2);
  }

The problem is that this funct is only callable with the 
following code:


  auto vlcPath = programFilesPath.opBinary!"~"(`VideoLAN\VLC`);

And it is not callable using the ~ operator directly. It says 
unable to call with types  FilePath and string


When I rewrite the opBinary funct as a member of the FilePath 
struct, everything is working fine. The problem is only happening 
when opBinary is a global funct. (I'm using LDC Win64)


Is it a bug or is there an explanation to this?


Re: Problem with opBinary

2018-11-14 Thread realhet via Digitalmars-d-learn

Thanks, this make it clear.
(This also explains the existence of opBinaryRight)


Re: LDC2 win64 calling convention

2018-11-29 Thread realhet via Digitalmars-d-learn

On Wednesday, 28 November 2018 at 21:58:16 UTC, kinke wrote:
You're not using naked asm; this entails a prologue (spilling 
the params to stack etc.). Additionally, LDC doesn't really 
like accessing params and locals in DMD-style inline asm, see 
https://github.com/ldc-developers/ldc/issues/2854.


You can check the final asm trivially online, e.g., 
https://run.dlang.io/is/e0c2Ly (click the ASM button). You'll 
see that your params are in R8, RDX and RCX (reversed order as 
mentioned earlier).


Hi again.

I just tried a new debugger: x64dbg. I really like it, it is not 
the bloatware I got used to nowadays.


It turns out that LDC2's parameter/register handling is really 
clever:


- Register saving/restoring: fully automatic. It analyzes my asm 
and saves/restores only those regs I overwrite.
- Parameters: Reversed Microsoft x64 calling convention, just as 
you said. Parameters in the registers will be 'spilled' onto the 
stack no matter if I'm using them by their names or by the 
register. Maybe this is not too clever but as I can use the 
params by their name from anywhere, it can make my code nicer.
- Must not use the "ret" instruction because it will take it 
literally and will skip the auto-generated exit code.


In conclusion: Maybe LDC2 generates a lot of extra code, but I 
always make longer asm routines, so it's not a problem for me at 
all while it helps me a lot.




LDC2 win64 calling convention

2018-11-28 Thread realhet via Digitalmars-d-learn

Hi,

Is there a documentation about the win64 calling convention used 
with LDC2 compiler?


So far I try to use the Microsoft x64 calling convention, but I'm 
not sure if that's the one I have to. But it's not too accurate 
becaues I think it uses the stack only.


https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention

I'm asking for Your help in the following things:

1. Is there register parameters? (I think no)
2. What are the volatile regs? RAX, RCX, RDX, XMM6..XMM15?
3. Is the stack pointer aligned to 16?
4. Is there a 32 byte shadow area on the stack?

Thank you!


Re: LDC2 win64 calling convention

2018-11-28 Thread realhet via Digitalmars-d-learn

Thank You for the explanation!

But my tests has different results:

void* SSE_sobelRow(ubyte* src, ubyte* dst, size_t srcStride){ asm{
  push RDI;

  mov RAX, 0; mov RDX, 0; mov RCX, 0; //clear 'parameter' 
registers


  mov RAX, src;
  mov RDI, dst;

  //gen
  movups XMM0,[RAX];
  movaps XMM1,XMM0;
  pslldq XMM0,1;
  movaps XMM2,XMM1;
  psrldq XMM1,1;
  pavgb XMM1,XMM0;
  pavgb XMM1,XMM2;
  movups [RDI],XMM1;
  //gen end

  pop RDI;
}}

When I clear those volatile regs that are used for register 
calling, I'm still able to get good results.
However when I put "mov [RBP+8], 0" into the code it generates an 
access violation, so this is why I think parameters are on the 
stack.


What I'm really unsire is that the registers I HAVE TO save in my 
asm routine.
Currently I think I only able to trash the contents of RAX, RCX, 
RDX, XMM0..XMM5 based on the Microsoft calling model. But I'm not 
sure what's the actual case with LDC2 Win64.


If my code is surrounded by SSE the optimizations of the LDC2 
compiler, and I can't satisfy the requirements, I will have 
random errors in the future. I better avoid those.


On the 32bit target the rule is simpe: you could do with all the 
XMM regs and a,c,d what you want. Now at 64bit I'm quite unsure. 
:S


Multitasking question: Making a picture viewer, loading lots of images in the background

2019-04-02 Thread realhet via Digitalmars-d-learn

Hi,

I'm writing a picture browser program and I'd like to ask for a 
bit of assistance.


My app is basically a Win32 window with an OpenGL surface. 
Currently I'm able to display a lot of pictures in it. The 
decompression of the bitmaps take place at the beginning of the 
program.


I want to make this more user friendly, so at first I only draw 
placeholders for the pictures while the actual loading and 
decompression is happening on worker threads.


I used std.concurrency.spawn. The parameters are the filename, 
and an index. After the decompression I let the main thread know 
about there is a bitmap it should upload to a texture later. I do 
it using synchronize, it works without error and was really easy 
to implements in D.


My problem is that when I launch 1000 spawn(), the work overload 
on the main thread is so heavy that the 60FPS timer which is 
refreshing the windows never can be called. Obviously spawn() is 
not the right choice for this.


In my previous projects I addressed this by creating 
NumberOfProcessorThreads threads,and locked them on specific 
ProcessorThreads by using ProcessAffinity, so the main thread has 
enough time to generate fluid user interface while the other 
worker threads used 100%CPU for the fastest processing.


I also remember that with OPENMP I was also able to lock workers 
onto specific ProcessorThreads, it also worked fine.


But how can I do this elegantly in D?

Thanks in advance!


(Also I'm not sure how spaw()-n is working exactly. Is it creates 
a new process for every spawn() call, or is it assigns the task 
to one of the N worker processes? 1000 CreateProcess() api calls 
would be not so nice. I just wanna know it in order to avoid it.)


Re: Multitasking question: Making a picture viewer, loading lots of images in the background

2019-04-03 Thread realhet via Digitalmars-d-learn

On Wednesday, 3 April 2019 at 04:09:45 UTC, DanielG wrote:
My understanding is that there's no benefit to creating more 
than the number of hyperthreads your CPU


Yes.

I'm just searching for a higher abstraction to manage this easily 
in D. I've already did it years ago on Delphi. (-> Manage N 
worker threads, and only put light stress on the thread which is 
running on the same core as the main thread.) Later it was easier 
to make it in OpenMP, and now I'm just looking for an even 
prettier way in DLang.


Also it's good to know what happens inside. I've checked Resource 
Monitor, and as you said, the thread count reached above 1000 in 
the first 3 seconds of running the program.
But after that something unusual happens: While my overall CPU 
usage was still high, the number of threads dropped down to 15, 
and the remaining 20 seconds of processing was don like this.


But still, while all the processing, the main thread got no cpu% 
at all, it was able to render only the very first frame, the one 
that displayed the empty 'loading in progress' images. After 23 
sec I was able to see all the 1000 pictures.


You should probably be looking at std.parallelism (TaskPool etc) 
for this.


Thank you for mentioning, this 
std.parallelism.Task.executeOnNewThread will be the next test. Is 
that behaving the same way like 'spawn'? From its name, I don't 
think so, but I'll find out.


check if _argument[0] is a descendant of a specific class.

2019-06-08 Thread realhet via Digitalmars-d-learn

Hi, I'm googling since an hour but this is too much for me:

class A{}
class B:A{}

void foo(...){
  if(_arguments[0]==typeid(A)){
//obviously not works for B
  }
  if(_arguments[0]  is_a_descendant_of A){
//how to make it work for both A and B?
  }
}

--

Also I tried to write a funct to compare classes by TypeInfo, but 
the TypeInfo.next field is not works in the way as I thought. It 
gives null, so the following code doesn't work.


auto isClass(C)(TypeInfo i){
  if(i==typeid(C)) return true;
  auto n = i.next;
  return n is null ? false : n.isClass!C;
}

I just wanna check if a compile_time _argument[0] is a descendant 
of a class or not.


I also tried (is : ) but without luck.

Thank you.



Variadic template parameters, refactor a long chain of static if's to 'functions'.

2019-06-11 Thread realhet via Digitalmars-d-learn

Hi again,

I'm trying to do variadic parameter processing, and I have the 
following function that works fine:


  static bool same(T1, T2)(){
pragma(msg, "same? "~T1.stringof~" "~T2.stringof);
return is(immutable(T1)==immutable(T2));
  }

  Btn btn(T...)(string params, T args){
enum captureIntID = true,
 captureBoolEnabled = true,
 captureFunct = true;

Args r; //Arg is a struct to store all the possible 
parameters in runtime

static foreach(a; args){
  //process id parameter
   static if(same!(typeof(a), id)) r.id = a.val;
  else static if(captureIntID && (same!(typeof(a), int) || 
same!(typeof(a), uint))) r.id = a;


  //process enabled/disabled
  else static if(same!(typeof(a), enabled )) r.enabled = 
a.val;
  else static if(same!(typeof(a), disabled)) r.enabled = 
!a.val;
  else static if(captureBoolEnabled && same!(typeof(a), bool) 
) r.enabled = a;


  //process data events
  else static if(same!(typeof(a), onClick  )) 
r.events.onClick   = a.f;
  else static if(same!(typeof(a), onPress  )) 
r.events.onPress   = a.f;
  else static if(same!(typeof(a), onRelease)) 
r.events.onRelease = a.f;
  else static if(same!(typeof(a), onChange )) 
r.events.onChange  = a.f;
  else static if(same!(typeof(a), onTrue   )) r.events.onTrue 
   = a.f;
  else static if(same!(typeof(a), onFalse  )) 
r.events.onFalse   = a.f;
  else static if(same!(typeof(a), onBool   )) r.events.onBool 
   = a.f;
  else static if(typeof(a).stringof.startsWith("void 
delegate()")) r.events.onClick = a;
  else static if(typeof(a).stringof.startsWith("void 
delegate(bool)")) r.events.onBool = a;


  else static assert(false, "Unsupported type 
"~typeof(a).stringof);

}

return new Btn(params, r.id, r.enabled, r.events);
  }


The long chain of is's are required to be able to show the error 
message at the end when an unhandled parameter type is found.


I will have more of these and want to reuse these ifs in other 
functions as well, so I decided to take out the first 2 if's and 
put it into a template function:


  static bool processId(bool captureIntId, alias r, alias a)(){
mixin("alias ta = typeof("~a.stringof~");");
pragma(msg, "ta "~ta.stringof);
 static if(same!(ta, id)) { r = a.val; return true; }
else static if(captureIntId && (same!(ta, int) || same!(ta, 
uint))) { r = a; return true; }

else return false;
  }

later I call it with:

  static if(processId!(true, r.id, a)){}
  else static if(...

'a' is the variadic foreach variable (_param_1 and so on),
'r.id' is the result field from an Arg structure.
Both 'a' and 'r.id' are existing and compiling, also the pragma 
messages are good, I see it can find the right types, but I have 
the following error for every variadic parameter:


Error: template instance processId!(true, id, _param_1) 
processId!(true, id, _param_1) is nested in both Args and btn


id is a struct. And also a field in the Args struct. I changed it 
to id1 in the Args struct ant the error remains the same.
Everything resides in the scope of a class called 
ContainerBuilder.


Is there a way to do this elegantly?
Maybe if I put everything in a very large chain of if's and 
enable the required parameters with a set of flags, but that's 
not structured well, and also needs the biggest possible set of 
runtime parameter storage to store the processed parametest.


Here's an example using the above function:
btn(`Yes flex=1`, id(54231), enabled(true), { lastClickedBtn = 
"Yes"; hehe = true; })

checkbox("Checkbox_1", 12345432, (bool b){ hehe = b; })

I will have a lot of controls and a lot of parameter types. I 
wanna do something like in the old VisualBasic, where you can 
skip a lot of default parameters, and also access the only few 
you need by name. Something like this: btn("caption", 
hint:"blabla", icon:"icon.ico"), but as I currently know this is 
not implemented in D.


Thank You in advance!




Re: check if _argument[0] is a descendant of a specific class.

2019-06-08 Thread realhet via Digitalmars-d-learn

On Saturday, 8 June 2019 at 21:25:41 UTC, Adam D. Ruppe wrote:

On Saturday, 8 June 2019 at 21:24:53 UTC, Adam D. Ruppe wrote:

_arguments is a compile time construct, it is a run time thing.


err i meant is *NOT* a compile time construct


Thank You for the fast help!

At first I was happy to find the variadic example and didn't even 
realized, that was the runtime version.


Now it works correctly with the base class check, and also it is 
now static and fast:


static foreach(a; args){
  static if(is(typeof(a)==string)){
//...
  }else
  static if(is(typeof(a) : Cell)){
if(a !is null){
  //...
}
  }else
  static if(is(typeof(a)==TextStyle)){
//...
  }else{
static assert(0, "Unsupported type: "~typeof(a).stringof);
  }
}



Re: Variadic template parameters, refactor a long chain of static if's to 'functions'.

2019-06-28 Thread realhet via Digitalmars-d-learn

On Tuesday, 11 June 2019 at 13:22:26 UTC, Adam D. Ruppe wrote:

On Tuesday, 11 June 2019 at 09:26:56 UTC, realhet wrote:

  static bool processId(bool captureIntId, alias r, alias a)(){
mixin("alias ta = typeof("~a.stringof~");");


As I have been saying a lot, mixin and stringof should almost 
never be used together. You could write this a lot easier:

...


Thank you for the long example, it helped me a lot!

The thing is now capable of:

- getting a specific type of parameter -> 
args.paramByType!(string[int]).writeln;


- including wrapper structs. In that case, optionally can fall 
back to the type inside the struct.


- handle and call events (structs or fallback as well)

- It is super easy now to make a function that can process a 
specific set of events:

struct onClick  { void delegate() val; }
...
struct onHold   { void delegate() val; }

void processBtnEvents(T...)(bool click, bool state, bool chg, 
T args){
  if(click) args.paramCall!(onClick, true/*fallback to pure 
delegate*/);

  if(state) args.paramCall!onHold;
  if(chg){
args.paramCall!onChange;
if(state) args.paramCall!onPress;
 else args.paramCall!onRelease;
  }
}

- Also I've found a way to exchange state values (for example a 
bool for a CheckBox control):

  - I can give it a pointer to a bool
  - Or I can give a getter and 0 or more setter(s): bool 
delegate(), void delegate(bool)

  - Can be functionPointers too, not just delegates.
  - example:
void fIncrementer(T...)(T args){
  paramGetterType!T x;
  args.paramGetter(x);
  x = (x + 1).to!(paramGetterType!T);
  args.paramSetter(x);
}
  - it is letting me use enumerated types too -> I will not have 
to write anything, and there will be an automatic 
RadioButtonGroup on the screen, just bu mentioning that variable. 
It will be awesome!


- Sorry for the lot of string processing and some mixin()s :D At 
the end of the code below, I've learned a lot while being able to 
write nicer code.


Thank you for your example code, I've learned a lot from it.

--
private{
  bool is2(A, B)() { return is(immutable(A)==immutable(B)); }

  bool isBool  (A)(){ return is2!(A, bool  ); }
  bool isInt   (A)(){ return is2!(A, int   ) || is2!(A, uint  ); }
  bool isFloat (A)(){ return is2!(A, float ) || is2!(A, double); }
  bool isString(A)(){ return is2!(A, string); }

  bool isSimple(A)(){ return isBool!A || isInt!A || isFloat!A || 
isString!A; }


  bool isGetter(A, T)(){
enum a = A.stringof, t = T.stringof;
return a.startsWith(t~" delegate()")
|| a.startsWith(t~" function()");
  }
  bool isSetter(A, T)(){
enum a = A.stringof, t = T.stringof;
return a.startsWith("void delegate("~t~" ")
|| a.startsWith("void function("~t~" ");
  }
  bool isEvent(A)(){ return isGetter!(A, void); } //event = void 
getter


  bool isCompatible(TDst, TSrc, bool compiles, bool 
compilesDelegate)(){

return (isBool  !TDst && isBool  !TSrc)
|| (isInt   !TDst && isInt   !TSrc)
|| (isFloat !TDst && isFloat !TSrc)
|| (isString!TDst && isString!TSrc)
|| !isSimple!TDst && (compiles || compilesDelegate); 
//assignment is working. This is the last priority

  }
}

auto paramByType(Tp, bool fallback=false, T...)(T args){
  Tp res;

  enum isWrapperStruct = __traits(hasMember, Tp, "val") && 
Fields!Tp.length==1; //is it encapsulated in a wrapper struct?  
-> struct{ type val; }


  enum checkDuplicatedParams = q{
static assert(!__traits(compiles, duplicated_parameter), 
"Duplicated parameter type: %s%s".format(Tp.stringof, fallback ? 
"("~typeof(Tp.val).stringof~")" : ""));

enum duplicated_parameter = 1;
  };

  static foreach_reverse(idx, t; T){
//check simple types/structs
static if(isCompatible!(typeof(res), t, __traits(compiles, 
res = args[idx]), __traits(compiles, res = 
args[idx].toDelegate))){
  static if(__traits(compiles, res = args[idx]))   
res = args[idx];else res = args[idx].toDelegate;

  mixin(checkDuplicatedParams);
}else
//check fallback struct.val
static if(fallback && isWrapperStruct && 
isCompatible!(typeof(res.val), t, __traits(compiles, res.val = 
args[idx]), __traits(compiles, res.val = args[idx].toDelegate))){
  static if(__traits(compiles, res.val = args[idx]))  
res.val = args[idx];  
  else res.val = args[idx].toDelegate;

  mixin(checkDuplicatedParams);
}
  }

  static if(isWrapperStruct) return res.val;
else return res;
}

void paramCall(Tp, bool fallback=false, T...)(T args){
  auto e = paramByType!(Tp, fallback)(args);
  static assert(isEvent!(typeof(e)), "paramCallEvent() error: %s 
is not an event.".format(Tp.stringof));

  if(e !is null) e();
}

template paramGetterType(T...){
  static foreach(t; T){
static 

Re: Can I remove an element from a global associative array from within a class destructor?

2019-08-03 Thread realhet via Digitalmars-d-learn
On Saturday, 3 August 2019 at 05:33:05 UTC, Jonathan M Davis 
wrote:
On Friday, August 2, 2019 5:13:10 PM MDT realhet via 
Digitalmars-d-learn wrote:

Hi,
...


Thank you!

Now I have 2 solutions in mind:
1. If I only want to track the count and totalBytes for a 
specific kind of reference, I will be able update those from the 
destructor.
2. If I wanna track all instances of resources, I will use 2 
classes instead of one class and an associative array:
- When I create a resource, I create class1 for the statistics, 
and store them in an assocArray. Then I create a class2 and 
inside it there is a reference to class1. Class2 will be given to 
the user. If the user don't use it anymore, the GC will destroy 
class2, and in it's destructor it will mark a field in class1. 
And it will be periodically checked, so the actual deletion of 
the GLBuffer and other statistics will be done by me.
With millions of resources it will be slow, but for a few 
thousand it's ok. (I can also put them in a hierarchy, but the 
most important is not to alloc/dealloc from ~this())


I hope it will be stable :D

Thank You again!




Can I remove an element from a global associative array from within a class destructor?

2019-08-02 Thread realhet via Digitalmars-d-learn

Hi,

I tried to make some resource statistict for my OpenGL Buffer 
objects:



//here are the things that hold the statistics.
private __gshared{ size_t[int] textureSizeMap, bufferSizeMap; }

struct GLCounters{
  int programs, shaders, textures, buffers;
  size_t textureSize, bufferSize;
}
__gshared GLCounters glCounters;

...

//And this is the buffer creation.
int genBuffer(size_t size){
  int res; glGenBuffers (1, ); glChk;
  glCounters.buffers ++;
  glCounters.bufferSize  += size;
  bufferSizeMap [res] = size;
  writefln("buffer allocated %d %d", res, size);
  return res;
}

//Finally, this is the deallocation. If it is called from the GC 
(when it destroys a class), it has a big chance to throw an 
Invalid Memory Operation exception.


void deleteBuffer (int handle){
  if(!handle) return;
  glDeleteBuffers (1, ); glChk;
  glCounters.buffers --;
  glCounters.bufferSize  -= bufferSizeMap [handle];
  writefln("buffer deallocated %d %d", handle, bufferSizeMap 
[handle]);

  bufferSizeMap.remove(handle); <- this is the problematic part.
}


Today I read the documentation about structs, unions and classes, 
but I haven't find any restrictions for the ~this() destructors.


Is there some extra rules regarding the GC and what I must not do 
in the destructors?


I think the destructor always called in the same thread where the 
instance was created. This can't be the case.
But what I can guess is: The GC makes a collection and calls my 
destructor and inside I do something and the GC calls a 
collection again recursively. But it seems a bit crazy, so I 
think it's not the case :D


Please help me solve this!

*I'm using LDC 1.6.0 Win64




How to create a custom max() function without the ambiguity error.

2019-12-06 Thread realhet via Digitalmars-d-learn

Hi,

I'm trying to use a popular function name "max", and extend it 
for my special types:


For example:

module utils;
MyType max(in MyType a, in MyType a){...}  //static function

struct V3f{
  V3f max(in V2f b){...} //member function
}

module gl3n;
vec3 max(in vec3 a, in vec3 a) //another static function in 
different module


I also want to use std.algorithm.comparison.max as well.


I know that the ambiguity error can be avoided by public 
importing all the various max implementations into one place, but 
how to do this when I want to use 3 modules? Need a 4th module to 
combine them all? Is there a nicer way?
Another question that is it possible to extend the the template 
function "to" in more than one module and use it easily from my 
main project modules?




Re: How to create a custom max() function without the ambiguity error.

2019-12-06 Thread realhet via Digitalmars-d-learn
On Friday, 6 December 2019 at 13:04:57 UTC, Ferhat Kurtulmuş 
wrote:

On Friday, 6 December 2019 at 12:34:17 UTC, realhet wrote:

Hi,

I'm trying to use a popular function name "max", and extend it 
for my special types:


For example:

module utils;
MyType max(in MyType a, in MyType a){...}  //static function

struct V3f{
  V3f max(in V2f b){...} //member function
}

module gl3n;
vec3 max(in vec3 a, in vec3 a) //another static function in 
different module


I also want to use std.algorithm.comparison.max as well.


I know that the ambiguity error can be avoided by public 
importing all the various max implementations into one place, 
but how to do this when I want to use 3 modules? Need a 4th 
module to combine them all? Is there a nicer way?
Another question that is it possible to extend the the 
template function "to" in more than one module and use it 
easily from my main project modules?


how about this:

import std.stdio;
import std.algorithm.comparison: max1 = max;

int max(int a, int b){ // dummy max
return 5;
}


void main(){
int a = 2;
int b = 3;

max1(a, b).writeln; // writes 3

}


Thx for answering!

This is what I want to avoid: To use extra identifiers or imports 
for the same semantic task.



module m1;
public import std.algorithm.comparison: max;
struct MyType{ int x;}
MyType max(in MyType a, in MyType a){ return a.x>b.x ? a : b; }


module main;
import m1;


From here: the max() is working for MyType and also for the types 
supported by std.algo.comparison.max.


BUT! What if I want to import another module which is overloading 
max?! It will be an ambiguity between m1 and the other module.
I'm searching for a clever solution, not just manually 
reimporting everything in every module where I use multiple 
modules which also manually reimporting those simple names like 
'max'.




Re: How to create a custom max() function without the ambiguity error.

2019-12-06 Thread realhet via Digitalmars-d-learn
On Friday, 6 December 2019 at 14:55:18 UTC, Ferhat Kurtulmuş 
wrote:

On Friday, 6 December 2019 at 13:25:24 UTC, realhet wrote:
On Friday, 6 December 2019 at 13:04:57 UTC, Ferhat Kurtulmuş 
wrote:

[...]


Thx for answering!

[...]


In d you can also use scoped imports: 
https://dlang.org/spec/module.html#scoped_imports


Yea, I know about that.
I also read the documentation about module imports, but in 
reality it feels like a bit different.


Here's my latest attempt on EXTENDING std.algorithm.max's 
functionality with a max operation on a custom type.
The type is the GLSL vec2 type which does the max operation 
component-wise.
The D std implementation uses the < operator, but with overriding 
that for my custom type it is impossible to realise. -> 
max(vec2(1, 2), vec2(2,1)) == vec2(2,2)


//So here is my helper module:
-
module testimport_a;

import std.algorithm;

struct vec2{ float x, y; }

auto max(in vec2 a, in vec2 b){
  return vec2(max(a.x, b.x),
  max(a.y, b.y));
}

import std.algorithm: max;

// and the main module 

module testimport_main;

import std.stdio, testimport_a;

void main(){
  auto a = vec2(1, 2),
   b = vec2(0, 5);

  max(a, b).writeln;
  max(1, 2).writeln;
}

--

Both of the max instructions are working nicely.
But here are all the things/restrictions which aren't as nice:

- in the imported module it is really important, to put my max() 
function BEFORE the std one. The std implementation tries to 
serve EVERYTHING, but it fails the compilation when it check the 
< operator (which is non-existent on 2d vectors).


- It doesn't matter if I use public import or not. When it finds 
any compatible max() inside the helper unit's functions, and its 
imported functionst that are specified by name, it will compile 
it.


- It is really important to import the original max() by name. 
(After my narrower max())


- If I import std.algorithm in the main module, no matter the 
order, it will fail. As the std.algorithm.max alone is unable to 
serve vec2 types.


- I tried to make one more module, to be able to use max on vec2, 
vec3 and everything else, but I failed. none of the my random 
guessing worked.


Map, filter and pure functions

2019-11-29 Thread realhet via Digitalmars-d-learn

Hi,

I have an input range.
I use the map! on it to transform using a function.
Finally I use filter! on the transformed data.

When I do a foreach on this, i noticed, that the transform 
function is called twice for each element.
If I remove the filter! it does only one transform function call 
per element.


Is this because the function is NOT PURE, so Phobos thinks that 
the function can give different results for the same input?


If I modify the function to be pure, will the transform function 
be called only once?


Re: Map, filter and pure functions

2019-11-29 Thread realhet via Digitalmars-d-learn

On Friday, 29 November 2019 at 15:30:22 UTC, realhet wrote:

...


Unfortunately function purity is not the answer.

I put a very long calculation into the transform function which 
is called from "map!".

And the "filter!" is making the "map!" call my function 2 times:
First for the "filter!" to decide it allows the element or not.
And second when the map! is passing it to the foreach() where I 
write the elements out.


Is there a solution for this performance issue?

Using functional programming, my program looks beautiful. But I 
need it to be optimal too.


//To be easier to understand, I want to make the following:
foreach(a; input){
  auto temp = slowFunction(a);
  if(check(temp))
writeln(temp);
}

//But the elegant functional form ->
input.map!slowFunction.filter!(a => check(a)).each!writeln;

//Produces the following unoptimal solution:
foreach(a; input){
  if(check(slowFunction(a)))
writeln(slowFunction(a));
}

Is there a functional way to fix this?

Thank you in advance!





Re: Map, filter and pure functions

2019-11-29 Thread realhet via Digitalmars-d-learn

On Friday, 29 November 2019 at 15:49:24 UTC, Paul Backus wrote:
It's actually a much simpler reason: filter calls .front twice 
for each element in its input (once to check if the value 
satisfies the predicate, and then again to return the value if 
it does), and the range returned by map doesn't save the value 
of .front between calls, so it has to re-compute it each time 
by calling the transform function.


This makes it clear.

In my case a cache which can access all the previous elements 
would be a too big thing, so I will do the filtering in a later 
stage manually. But most importantly, now I know what's going on, 
Thank You!


Re: Getting the initial value of a class field in compile time.

2020-02-08 Thread realhet via Digitalmars-d-learn

On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe wrote:

On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:
classinfo.m_init can be an option, but maybe there's a nicer 
way to do this?


eh the initializer i think is the best. you can sometimes 
shortcut it


pragma(msg, (new A).i);

which will call the ctor at ctfe and get the value. but if 
there isn't a default constructor that's harder. (of course at 
runtime you can yank it out of the init member... but ctfe will 
fail that i believe because of the reinterpret cast involved).


i can't think of a better way right now.


Thank you! It works!
Somehow I thought that 'new' is too much in CTFE, now I can 
rethink that.


Re: Getting the initial value of a class field in compile time.

2020-02-08 Thread realhet via Digitalmars-d-learn

On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote:

On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe wrote:


Using what I've learned:

class A{
  int i=42;

  void init(){ // reInitialize class fields
alias T = typeof(this);
mixin([FieldNameTuple!T].map!(n => n~"=(new T)."~n~";").join);
  }

}

(I also like to live dangerously with string mixins :D)


Getting the initial value of a class field in compile time.

2020-02-08 Thread realhet via Digitalmars-d-learn

Hello,

class A{
  int i = 42;
}

Is there a way to get that 42? (Input is the class A and the name 
of the field 'i')


A.i.init returns 0, so it doesn't care about the class.

classinfo.m_init can be an option, but maybe there's a nicer way 
to do this?


Thx!


Re: Getting the initial value of a class field in compile time.

2020-02-08 Thread realhet via Digitalmars-d-learn

On Sunday, 9 February 2020 at 00:15:47 UTC, Drug wrote:

On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:

Hello,

class A{
  int i = 42;
}

Is there a way to get that 42? (Input is the class A and the 
name of the field 'i')


A.i.init returns 0, so it doesn't care about the class.

classinfo.m_init can be an option, but maybe there's a nicer 
way to do this?


Thx!


Try A.init.i


I tried and A.init.stringof == "void()"

That generates a new question, what is void() ?
It has no sizeof property.
I guess it's the voidest of the voids in D :D


Re: Getting the initial value of a class field in compile time.

2020-02-09 Thread realhet via Digitalmars-d-learn

On Sunday, 9 February 2020 at 01:19:55 UTC, Paul Backus wrote:

On Sunday, 9 February 2020 at 00:57:05 UTC, realhet wrote:

On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote:

On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe

enum initValue = (new typeof(this)).tupleof[i];


Wow, thx! Accessing by index instead of name. Really powerful!



Re: Getting the initial value of a class field in compile time.

2020-02-08 Thread realhet via Digitalmars-d-learn

On Sunday, 9 February 2020 at 00:57:05 UTC, realhet wrote:

On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote:
On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe 
wrote:



mixin([FieldNameTuple!T].map!(n => n~"=(new T)."~n~";").join);

After checking it in the asm debugger, it turned out, that it 
evaluates (new T) in runtime. (Silly me, because the constructor 
can have side effects.)
So I first put the default values into an enum, and then do the 
assignment:


foreach(n; FieldNameTuple!T){{
  mixin("enum def = (new T).@; @ = def;".replace("@", n));
}}

And that became as fast as it can be:

mov dword ptr ds:[rax+10], 2A

Thanks for the help again.


Re: Getting the initial value of a class field in compile time.

2020-02-09 Thread realhet via Digitalmars-d-learn
On Sunday, 9 February 2020 at 02:25:56 UTC, Steven Schveighoffer 
wrote:

On 2/8/20 7:39 PM, realhet wrote:

On Sunday, 9 February 2020 at 00:15:47 UTC, Drug wrote:

On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:


Yea, I exactly ran into that "init" problem, I will avoid that, 
thx!


Information about the 'magic' field in object.Object class

2020-01-16 Thread realhet via Digitalmars-d-learn

Hello,
I'm try to figure out the contents od the base class instance in 
D, LDC Windows 64bit.

I'm sure that there is a 8 byte VMT pointer.
But unable to fund information about the remaining 8 byte. I 
guess it must be a unique 8byte (void* ?) identifier that is 
useful for Monitor. In a video someone mentioned this as 'magic'.


Is there a documentation about that 'magic' field? I'd love to 
use some bits in it if I'm sure about the consequences.


I have a really small object, only 32 bytes. At this point if I 
want to add a flag bit I have 3 choices:
- add a new field to the class -> effectively the instanceSize 
will grow by 50% (16bytes with alignment)

- compress the current 16bytes of data. -> eats more cpu
- Hide it somewhere 'magically'.

Thank You in advance!




Re: Information about the 'magic' field in object.Object class

2020-01-16 Thread realhet via Digitalmars-d-learn

On Thursday, 16 January 2020 at 14:32:24 UTC, Adam D. Ruppe wrote:

On Thursday, 16 January 2020 at 14:30:04 UTC, realhet wrote:

Is there a documentation about that 'magic' field?


I'm pretty sure the only fields in there are pointer to vtable 
and pointer to monitor object...


I have a really small object, only 32 bytes. At this point if 
I want to add a flag bit I have 3 choices:


Do you need virtual functions? If not, you could probably just 
make a struct instead.


Thank you both for the hints!

Yes I need virtual functions (this is the base class of my layout 
system: it can be a letter, a picture, or a paragraph of text.).


I've tried extern(C++) and it went down 8 bytes.

But the I tried the following:
synchronized(obj){ ... }
Compiles without a problem. Hmm...

I think I will use extern(C++) and later when I will have a big 
system to test, I will benchmark it. I'm sure that Monitor 
functionality is not needed for these objects, so that extra 8 
bytes will worth it.


Update:
- All of the child classes needed to be marked with extern(C++)
- static class members are not supported, only __gshared static.
- passing a delegate to a constructor of this class expects a 
(extern(C++) delegate) too.

- Internal compiler error: string[string] can not be mapped to C++

So extern(C++) is not good in the current case.

I will try to use that 8 byte magic illegally, and will see if it 
is unstable or not.
I will not do any synchronization, but I think the GC will crash 
upon releasing these objects.


Thx for the help!


Using the functions "map" and "any" on tuples in compile time.

2020-04-12 Thread realhet via Digitalmars-d-learn

Hello, anyone can help me make this better?

The functionality I want to achieve is: While serializing the 
fields of a struct, I want it to check the @STORED UDA on every 
field. If there is no fields are marked with @STORED, that means 
every field must be serialized. Otherwise only the marked one.


I had problems using map and any, so I come up with this lame 
foreach version: It works, but I think it does it in runtime.


bool anySTORED = false;
static foreach(fieldName; FieldNameTuple!T)
  mixin("anySTORED |= hasUDA!(data.*, STORED);".replace("*", 
fieldName));


static foreach(fieldName; FieldNameTuple!T){{
  mixin("const thisSTORED = hasUDA!(data.*, 
STORED);".replace("*", fieldName));
  if(thisSTORED || !anySTORED) 
mixin("streamAppend_json!(dense, fieldName)(st, data.*, 
nextIndent);".replace("*", fieldName));

}}

Thanks in advance!

(ps: I just love string mixins, I know :D)


Re: Using the functions "map" and "any" on tuples in compile time.

2020-04-12 Thread realhet via Digitalmars-d-learn

On Sunday, 12 April 2020 at 12:42:40 UTC, Harry Gillanders wrote:

On Sunday, 12 April 2020 at 11:17:39 UTC, realhet wrote:


I only remembered the __traits(identifier...), but completely 
forgot about the getMember.

And I never heard of anySatisfy.
My JSON serializer is beautiful now.

Thank You very much!


Is there an exception for access violation on LDC/win64?

2020-04-13 Thread realhet via Digitalmars-d-learn

Hi,

import std.stdio, std.exception;

void main(){
  class C{
void foo(){ writeln(123); }
  }

  C c;
  try{
writeln(1);
c.foo;// access violation here
writeln(2);
  }catch(Throwable t){
writeln("exception");
  }
  writeln(3);
}

When I run this code (using LDC2 64bit Windows), it silently 
crashes where the access violation happens and returns an 
%ERRORLEVEL% value of -1073741795 (-0x3FE3).


On the Online DLang Editor I get some more information:
Error: /tmp/onlineapp-cf8e338-8b2478 failed with status: -2
Error: message: Segmentation fault (core dumped)
Error: program received signal 2 (Interrupt)

This is better, but is there a trick to turn these system errors 
to an exception, so I would be able to get the location where it 
crashed in my source code?


The best I've found is this trick for Linux: 
https://forum.dlang.org/post/atxyappczlyvqyalv...@forum.dlang.org


That error message would be so usefull, but is there a way to do 
it on windows?


Re: linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-31 Thread realhet via Digitalmars-d-learn
On Thursday, 26 March 2020 at 14:52:36 UTC, Ferhat Kurtulmuş 
wrote:

On Sunday, 22 March 2020 at 18:43:50 UTC, realhet wrote:

Hello,

I'm try to use the latest LDC2 version: 1.20.0
Previously I used 1.6.0

[...]


Try to run the compiler in visual studio command line terminal.


I set up the environment variables with "ldc2\bin\msvcenv 
amd64", it calls that command prompt implicitly. That couldn't be 
a problem.


Re: linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-31 Thread realhet via Digitalmars-d-learn
On Tuesday, 24 March 2020 at 15:22:19 UTC, Steven Schveighoffer 
wrote:

On 3/24/20 10:28 AM, realhet wrote:

On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer
If this were Linux, I'd start using nm to search the object 
files for the symbol that is missing (like search for symbols 
defining hasToString), and see if it possibly might be mangled 
in a different way. I'm not sure what tools there are on 
Windows to do this.


-Steve


I've found a similar tool in MSVC, it's called DUMPBIN.
I was able to find that the linker errors were correct: I wasn't 
able to find even smaller substrings of that 
std.format.hasToString symbol, it was called like 4 times.


But I had a clue: A problem when trying to call hasToString on my 
struct, so I located all the references for that and I've found 
this thing:


//infoArray.enumerate.each!writeln;
//!!! LDC 1.20.0 win64 linker bug when using enumerate 
here!


//foreach(i, a; infoArray) writeln(tuple(i, a));
//!!! linker error as well

//foreach(i, a; infoArray) writeln(tuple(i, i+1));
//!!! this is bad as well, the problem is not related to own 
structs, just to tuples


foreach(i, a; infoArray) writefln("(%s, %s)", i, a);  //this 
works



Now I know that [LDC 1.20.0 win64 -allinst] has a problem 
generating the code for tuple parameters in std.format calls.

This was not a problem in 1.6.0

Now I go on and try my bigger projects.


Handle FormatSpec!char in the virtual toString() method of a class.

2020-05-13 Thread realhet via Digitalmars-d-learn

Hello,

Is there a way to the following thing in a class instead of a 
struct?


--
static struct Point
{
int x, y;

void toString(W)(ref W writer, scope const ref 
FormatSpec!char f)

if (isOutputRange!(W, char))
{
// std.range.primitives.put
put(writer, "(");
formatValue(writer, x, f);
put(writer, ",");
formatValue(writer, y, f);
put(writer, ")");
}
}
--

I think the problem is that the toString() in a class is virtual, 
and don't let me to have multiple overloaded methods.


Is there a way to let format() deal with classes too?

Thank You!


linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-22 Thread realhet via Digitalmars-d-learn

Hello,

I'm try to use the latest LDC2 version: 1.20.0
Previously I used 1.6.0

After fixing all the compiler errors and warnings, I managed to 
compile all the d source files to obj files, and I got 4 linking 
errors. I think all of them caused by the first 2:


1:
msvcrt.lib(initializers.obj) : warning LNK4098: defaultlib 
'libcmt.lib' conflicts with use of other libs; use 
/NODEFAULTLIB:library


2:
exceptions.obj : error LNK2019: unresolved external symbol 
_D3std6format__T11hasToStringTSQBd4json9JSONValueTaZ9__lambda2MFZ1S3putMFNaNbNiNfaZv referenced in function _D3std5range10primitives__T5doPutTSQBh6format__T11hasToStringTSQCj4json9JSONValueTaZ9__lambda2MFZ1STaZQCxFNaNbNiNfKQDdKaZv


Anyone knows how to solve these? Please help me!

I uploaded all the details to here: 
https://github.com/realhet/hetlib/blob/master/het/test/linkingerror.txt


Or if there is info about how to use the Microsoft 64bit linker 
with the newest version of LDC2 please let me no.
Or maybe an open source build tool that is up to date and I can 
extract the most recent linker parameters?

Is there a new VS Community version requirement?

I remember it was also tricky 2.5 years ago, since then it worked 
perfectly fine for me, but I just decided to use the latest LDC2 
and bumped to this.


Thank you for the assistance in advance!



Re: linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-23 Thread realhet via Digitalmars-d-learn
On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer 
wrote:


Make sure you don't have any stale objects left over in your 
project from the older build. Build everything clean from 
scratch.


-Steve


Thx, I double checked this. Then I attempted to link from the 
commandline and it worked. o.O So there must be some weirdness in 
my build tool which is fine with LDC2 1.6.0 but fails with 1.20.0 
:S


Re: linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-24 Thread realhet via Digitalmars-d-learn
On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer 
wrote:
Make sure you don't have any stale objects left over in your 
project from the older build. Build everything clean from 
scratch.


-Steve


After narrowing the problem, I fixed all warnings, and 
deprecations, and I have only one linker error now:


Compiler command line (LDC 1.20.0 Win64):
ldmd2 -vcolumns -c -op -allinst -Ic:\D\libs\ -m64 
-mcpu=athlon64-sse3 -mattr=+ssse3 -release -O -inline 
-boundscheck=off c:\D\libs\jsonizer\exceptions.d


Linker command line:
link /LIBPATH:c:\D\ldc2\lib64 /OUT:c:\D\libs\het\hdmd\hdmd.exe 
/MACHINE:X64 kernel32.lib user32.lib legacy_stdio_definitions.lib 
***All the required obj files*** druntime-ldc.lib phobos2-ldc.lib 
msvcrt.lib


Linker response (after demangling):
Microsoft (R) Incremental Linker Version 14.23.28105.4
Copyright (C) Microsoft Corporation.  All rights reserved.

-

exceptions.obj : error LNK2019: unresolved external symbol

pure nothrow @nogc @safe void 
std.format.hasToString!(std.json.JSONValue, 
char).__lambda2().S.put(char)


referenced in function

pure nothrow @nogc @safe void 
std.range.primitives.put!(std.format.hasToString!(std.json.JSONValue, char).__lambda2().S, char).put(ref std.format.hasToString!(std.json.JSONValue, char).__lambda2().S, char)


-

I've searched for the hasToString template, but this seems way 
too complicated for me.

This nested lambda template thing o.O

Here is the source code for the exceptions.obj file: 
https://github.com/rcorre/jsonizer/blob/master/src/jsonizer/exceptions.d


These are caused by some format() calls, I don't know why it is a 
problem now and it's totally OK with a 2017 version.


This nested std.range.primitives.put is weird for me. Maybe it's 
a bug because by the -CompileAllTemplateInstances flag? (That's 
not the normal use, I know: I comile all the objs, and while I 
work, I only compile the ones that changed (recursively ofc), and 
finally link. It's much faster this way on a 8 core machine.).






Re: linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-24 Thread realhet via Digitalmars-d-learn
On Tuesday, 24 March 2020 at 15:22:19 UTC, Steven Schveighoffer 
wrote:

On 3/24/20 10:28 AM, realhet wrote:

On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer


I managed to compile it with normal compilation.
The -allInst flag may be the problem.

I also had success by manual linking:

ldmd2 -vcolumns -Ic:\D\libs\ -m64 -mcpu=athlon64-sse3 
-mattr=+ssse3 -release -O -inline -boundscheck=off 
-of=c:\D\libs\het\hdmd\hdmd.obj c:\D\libs\het\hdmd\hdmd.d ... -c


link /LIBPATH:c:\D\ldc2\lib64 /OUT:c:\D\libs\het\hdmd\hdmd.exe 
/MACHINE:X64 kernel32.lib user32.lib legacy_stdio_definitions.lib 
c:\D\libs\het\hdmd\hdmd.obj druntime-ldc.lib phobos2-ldc.lib 
msvcrt.lib


So I will try to narrow the problem in Jsonizer.exceptions.d

For a 11k LOC project with 10 .d files when I only modify a few 
top level d files, and I already have the .obj files for the 
rest, the compilation time is only 5-10 seconds instead of the 40 
with the all in one compilation. I got used to this, so I will 
try anything to fix it :D


Re: linking obj files compiled with LDC2 1.20.0 on Win64

2020-03-24 Thread realhet via Digitalmars-d-learn

On Tuesday, 24 March 2020 at 16:35:56 UTC, realhet wrote:
On Tuesday, 24 March 2020 at 15:22:19 UTC, Steven Schveighoffer 
wrote:

On 3/24/20 10:28 AM, realhet wrote:

On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer


Now I have 2 of this:

megatexturing.obj : error LNK2019: unresolved external symbol

pure nothrow @nogc @safe void std.format.hasToString!(
  std.typecons.Tuple!(
ulong, "index", const(het.megatexturing.SubTexInfo), "value"
  ).Tuple, char
).__lambda1().S.put(char)

referenced in function

pure scope @safe bool 
std.format.FormatSpec!(char).FormatSpec.writeUpToNextSpec!(

  std.format.hasToString!(
std.typecons.Tuple!(
  ulong,
  "index",
  const(het.megatexturing.SubTexInfo),
  "value"
).Tuple,
char
  ).__lambda1().S
).writeUpToNextSpec(
  ref std.format.hasToString!(std.typecons.Tuple!(ulong, "index", 
const(het.megatexturing.SubTexInfo), "value").Tuple, 
char).__lambda1().S

)

And only with that format hasToString! template.
I hope I can locate something along this:
std.typecons.Tuple!(
  ulong, "index", const(het.megatexturing.SubTexInfo), "value"
)
Maybe it refers to a function parameter list in my program.

Something tells me that this should not be look like something 
recursive o.o


I'll search for that Linux tool on windows that you mentioned...


Getting FieldNameTuple including all base-classes.

2020-05-19 Thread realhet via Digitalmars-d-learn

Hi,

I was able to reach all the fields in a subclass using foreach 
and BaseClassesTuple, but is there a way to do this using 
functional programming primitives, but in compile time for tuples?


private template FieldNameTuple2(T) {
  enum FieldNameTuple2 = BaseClassesTuple!T.map!(S => 
FieldNameTuple!S).join;

}

This is obviously wrong, but is there a way to do it?

I've searched for FieldNameTuple and BaseClassesTuple, but 
without luck. It's weird because it seems like a common thing to 
do.


Thanks in advance!



Re: Handle FormatSpec!char in the virtual toString() method of a class.

2020-05-19 Thread realhet via Digitalmars-d-learn

On Thursday, 14 May 2020 at 19:01:25 UTC, H. S. Teoh wrote:
On Wed, May 13, 2020 at 12:26:21PM +, realhet via 
Digitalmars-d-learn wrote:


Thank You, very helpful!


Compile-time function call with transformed parameters

2020-10-14 Thread realhet via Digitalmars-d-learn

Hi,
Is there a way to make this in a nicer way without the string 
mixin?


private auto generateVector(CT, alias fun, T...)(in T args){
  static if(anyVector!T){
Vector!(CT, CommonVectorLength!T) res;
static foreach(i; 0..res.length) res[i] = mixin("fun(", 
T.length.iota.map!(j => 
"args["~j.text~"].vectorAccess!i").join(','), ")");

return res;
  }else{
return fun(args);
  }
}

The mixin expands to:
fun(args[0].vectorAccess!i, ..., args[$-1].vectorAccess!i)

And vectorAccess is a function with a template int parameter (i).

private auto vectorAccess(int idx, T)(in T a){
  static if(isVector!T) return a[idx];
   else return a;
}

I tried with staticMap, but that vectorAccess is a runtime thing. 
Other than that I have no idea. I'm 99% sure DLang has a nice 
thing for this, but can't find it yet.


Maybe it is possible to put a thing like this -> [ 
args[0].vectorAccess!i ] into an AliasSeq and then give that 
inside the fun(), but how can I generate effectively an array of 
code?


Thank you!



Struct initializer in UDA

2020-09-26 Thread realhet via Digitalmars-d-learn

Hi,

  struct S{int a, b, c=9, d, e, f;}

Is there a way or a trick to declare an UDA by using a nice 
struct initializer?


It would be nice to be able to use the form:

  @S{f:42} int a;  //or something similar to this.

instead of this longer and error-prone way:

  @S(0, 0, 0, 9, 0, 42) int a;


Re: What kind of mangling has the LDC2 -X JsonFile "deco" field?

2020-09-17 Thread realhet via Digitalmars-d-learn
On Thursday, 17 September 2020 at 04:01:11 UTC, Adam D. Ruppe 
wrote:

On Thursday, 17 September 2020 at 03:06:45 UTC, realhet wrote:

Anyone can help me telling how to decode these please?

Just prepend

_D4name


Thank you very much!


Re: Struct initializer in UDA

2020-09-27 Thread realhet via Digitalmars-d-learn

On Sunday, 27 September 2020 at 11:59:49 UTC, Anonymouse wrote:

On Sunday, 27 September 2020 at 10:17:39 UTC, realhet wrote:
On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse 
wrote:

On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:


That looks the closes to the python named parameters or the 
struct initializer.


For my use case this opDispatch trick seems to be more flexible 
than the named-parameters thing:


@(FieldProps().range(-360, 360).format("%.2f").caption("Turret 
rotation").unit("deg")) float alpha = 0;


for example if I use the name: "logRange" it can also set the 
isLogarithmic flag as a side effect to true inside the FieldProps 
struct. Just by choosing a slightly different name.


With this idealized format it would be not possible:
@FieldProps{ range: {-360, 360}, format:"%.2f", caption:"Turret 
rotation", unit:"deg"} float alpha = 0;


The more work inside the struct is not a problem, because I'm 
willing to use it from 1000 places. Also __traits(allMembers) can 
help.


Thank you!


Re: Struct initializer in UDA

2020-09-27 Thread realhet via Digitalmars-d-learn

On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse wrote:

On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:
The closest I can get is @(S.init.c(9).f(42)) with use of 
opDispatch, which is easier to read but still ugly.


All I can get is that the
- an identifier of a member is stronger than the opDispatch. -> 
Error: function expected before (), not S(0, 0).c of type int
- and if I prefix it with '_' it ruins toString. -> Error: no 
property toString for type onlineapp.S



import std.stdio, std.range, std.algorithm, std.traits, std.meta, 
std.conv, std.string, std.uni, std.meta, std.functional, 
std.exception;


struct S{
int a, b;

auto opDispatch(string name, T)(T value)
if(name.startsWith("_"))
{
mixin(name[1..$], "= value;");
return this;
}
}

void main(){
S.init._a(5).writeln;
}


Now I'm more confused, as the compiler completely ignores the 
if(name.startsWith("_")) constraint o.O


Re: Getting Field Names of a specific UDA in compile time.

2020-10-03 Thread realhet via Digitalmars-d-learn

On Saturday, 3 October 2020 at 14:00:30 UTC, Adam D. Ruppe wrote:

On Saturday, 3 October 2020 at 13:10:31 UTC, realhet wrote:
I only managed to get the string[] by making a static foreach, 
but I don't know how to put that in an enum xxx = ...; 
statement.


There's always other ways but general rule: if you can get it 
one way, just wrap that up in a function and call that function 
for your enum initializer.


string[] your_function() {
 // implementation here you already have
 return it;
}

enum NodeNames = your_function();


Though with arrays btw `static immutable` tends to give better 
results than `enum` since it avoids extra allocations.


I tried it to put into a function:

auto getSymbolNamesByUDA(T, string uda)(){
string[] res;
static foreach(a; getSymbolsByUDA!(T, uda)) res ~= a.stringof;
return res;
}

class Printer{
@("NODES") int gem1, gem2, gem3, gem4, gem5, head1, head2, 
head3, head4;

alias Nodes = getSymbolsByUDA!(typeof(this), "NODES");
enum NodeNames = getSymbolNamesByUDA!(typeof(this), "NODES");
}

void main(){
static foreach(n; Printer.Nodes) n.stringof.writeln;
Printer.NodeNames.writeln;
}

Up until this point, the alias declaration was before the enum 
declaration.

It gives an error:
Error: unknown, please file report on issues.dlang.org

But now I tried to comment out the alias declaration and it 
worked. It also works when I put the alias declaration after the 
enum:

enum NodeNames = getSymbolNamesByUDA!(typeof(this), "NODES");
alias Nodes = getSymbolsByUDA!(typeof(this), "NODES");

Same behavior with "static immutable".
My initial intention was to use the Nodes alias to get the name 
strings out of it. Now it needs more copy paste but it works.


This is weird o.O

Thank you!


Getting Field Names of a specific UDA in compile time.

2020-10-03 Thread realhet via Digitalmars-d-learn

Hi,

class Printer{
  @("NODES") int gem1, gem2, gem3, gem4, gem5, head1, head2, 
head3, head4;


  import std.traits, std.meta;
  alias Nodes = getSymbolsByUDA!(typeof(this), "NODES");
  enum NodeNames = ["gem1", "gem2", ];
}

Is there a way to make an enum like the above with compile time 
programming?
I only managed to get the string[] by making a static foreach, 
but I don't know how to put that in an enum xxx = ...; statement.


Making alias of a struct field needs "this".

2020-06-02 Thread realhet via Digitalmars-d-learn

Hello,

I have a 2 level nested struct structure with nice descriptive 
field names.
And I thought it will be easy to alias those identifierLists with 
a few letter names and do some calculations on them.

But I'm having an error.

struct A{
  struct B{ int c; }
  B b;

  auto f(){
alias d = b.c;
return d;  //Compiler Error: need 'this' for c of type int.
  }
}

There's the this and it's called "b."

Why is this? If I copy paste the aliased expression "b.c", it 
compiled fine.


Thanks in advance!



Re: Getting FieldNameTuple including all base-classes.

2020-05-20 Thread realhet via Digitalmars-d-learn

On Wednesday, 20 May 2020 at 09:03:51 UTC, realhet wrote:

On Wednesday, 20 May 2020 at 01:18:24 UTC, Paul Backus wrote:

On Tuesday, 19 May 2020 at 23:15:45 UTC, realhet wrote:


With this mod it also works with structs:

template AllClasses(T){
static if(is(T == class))
alias AllClasses = Reverse!(AliasSeq!(T, 
BaseClassesTuple!T[0..$-1]));

else
alias AllClasses = T;
}



Re: Getting FieldNameTuple including all base-classes.

2020-05-20 Thread realhet via Digitalmars-d-learn

On Wednesday, 20 May 2020 at 01:18:24 UTC, Paul Backus wrote:

On Tuesday, 19 May 2020 at 23:15:45 UTC, realhet wrote:
I think what you want is `std.meta.staticMap`. Something like 
this:


alias FieldNameTuple2(T) = staticMap!(FieldNameTuple, 
BaseClassesTuple!T);


class A { int a, a1; }
class B : A { int b; }
class C : B { int c, c1; }

alias AllClasses(T) = Reverse!(AliasSeq!(T, 
BaseClassesTuple!T[0..$-1]));

alias AllFieldNames(T) = staticMap!(FieldNameTuple, AllClasses!T);

void main(){
  static foreach(T; "ABC") 
mixin("AllFieldNames!"~T~".stringof.writeln;");

}

That statticMap unlike the normal map, it also joins the AliasSeq 
at the end. Just what I needed.


Thank You!


Re: Making alias of a struct field needs "this".

2020-06-02 Thread realhet via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 13:10:55 UTC, Paul Backus wrote:

On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:
mixin("@property auto ", k, "() const { return ", v, "; }");


Wow, string mixin can process comma separated list, I gotta 
remember this, thanks!





Re: Making alias of a struct field needs "this".

2020-06-02 Thread realhet via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 13:37:25 UTC, Stanislav Blinov wrote:

On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:
Try UDAs instead of a map:

struct A {
struct G {
@("hauteur") int height;
}


Good idea, thx! I already using UDA's for range and measurement 
units.


  struct Profile{ @STORED:
@UNIT("mm") @RANGE(0, 100)  float radius = 21;

I gonna need one more reasonably named UDA struct.


Re: Making alias of a struct field needs "this".

2020-06-02 Thread realhet via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:

On Tuesday, 2 June 2020 at 09:10:03 UTC, Ali Çehreli wrote:

On 6/2/20 1:56 AM, realhet wrote:


Oh and I can put that function generator mixin thing into a 
template as well, that way it is reusable and much nicer.


There are a lot of possibilities in D, I love it!


Re: Making alias of a struct field needs "this".

2020-06-02 Thread realhet via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 09:10:03 UTC, Ali Çehreli wrote:

On 6/2/20 1:56 AM, realhet wrote:

> struct A{
>struct B{ int c; }
>B b;
>
>auto f(){
>  alias d = b.c;

The spec explicitly says it's not legal: "Aliases cannot be 
used for expressions" (Item 10):


  https://dlang.org/spec/declaration.html#alias

I use nested functions for such cases:

  auto f(){
auto d() {
  return b.c;
}
return d;
  }

Ali


Thanks for responses:

I did it that way:
  private enum fieldMap = [ // simple names for descriptive and 
structured fields

"hauteur"   : "general.height",
"rayon" : "profile.radius",
"plage" : "profile.plage",
"offsetv"   : "profile.verticalOffset",
"offseth"   : "profile.horizontalOffset",
"varrad0"   : "profile.linearVariationBottom",
"varrad1"   : "profile.linearVariationTop",
"amplitude" : "periphery.amplitude",
"varlin0"   : "periphery.linearVariationBottom",
"varlin1"   : "periphery.linearVariationTop",
"varsinp"   : "periphery.cosinusVariationPlage",
"varsino"   : "periphery.cosinusVariationOffset",
"periodes"  : "periphery.nbPeriods",
"revolution": "periphery.turn"
  ];

  static foreach(k, v; fieldMap){ mixin("@property auto $() 
const{ return #; }".replace("$", k).replace("#", v)); } //I know, 
i know -> AliasSeq :D


But it doesn't look nice.

I've found some additional info here: 
https://forum.dlang.org/thread/hresorfqicczofnrc...@forum.dlang.org?page=2


Seems like I must not except the same from an alias template 
paramater and from the alias construct. The alias construct is 
for a single symbol.


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread realhet via Digitalmars-d-learn
On Sunday, 20 September 2020 at 14:54:09 UTC, Steven 
Schveighoffer wrote:

On 9/20/20 9:30 AM, realhet wrote:
ref inout(int) x() inout { return array[0]; }


This doesn't work when I type:
v.x++;

I want to make a similar type like the GLSL vectors. Where the 
following thing is valid:

vec4 a, b;
a.yzw = b.xzy;

On the left there is a contiguous area of the vector a. It just 
starts form the 1th element, not form the 0th: a[1..4].  It could 
be work as an lvalue.


On the right there is a non-contiguous swizzle: [b.x, b.z, b.y]. 
But because it is 3 element wide, it can be assigned to the 
lvalue "a.yzw". This value cannot be an lvalue because the order 
of the elements are not the same as in memory. So it must 
returned as a const.


Here's what I achieved so far:

private enum swizzleRegs = ["xyzw", "rgba", "stpq"]; //vector, 
color, and texture component letters


struct Vec(CT, int N)
if(N>=2 && N<=4){
  alias VectorType = typeof(this);
  alias ComponentType = CT;
  enum VectorTypeName = ComponentTypePrefix ~ "vec" ~ N.text;

  CT[N] array = [0].replicate(N).array; //default is 0,0,0, not 
NaN.  Just like in GLSL.

  alias array this;
  enum length = N;

  ...

  static foreach(regs; swizzleRegs)
static foreach(len; 1..N+1)
  static foreach(i; 0..N-len+1)
static if(len==1){
1)mixin(format!"auto %s() const { return array[%s]; 
}"(regs[i], i));
2)mixin(format!"ref  %s()   { return array[%s]; 
}"(regs[i], i));

}else{
3)mixin(format!"auto %s() const { return Vec!(CT, 
%s)(array[%s..%s]); }"(regs[i..i+len], len, i, i+len));
4)mixin(format!"ref  %s()   { return *(cast(Vec!(CT, 
%s)*) (array[%s..%s])); }"(regs[i..i+len], len, i, i+len));

}

}

So what I feel, the mixin()-s are a bit nasty :D But sufficient 
for the following two criteria:


1.  immutable vec3 a; a.xy.writeln; // displays a const vec2 
casting a constant memory lovation to vec2  -> 3)


2.  vec3 b;  b.g++;  // accessing the 2. component(g=green, 
1based) of a vec3 with a memory reference because it is mutable.


I only want lvalues from swizzle combinations that are adjacent 
in memory, so I can cast them. For all the rest I'm using 
opDispatch(string def)() with a strict constraint on the string 
'def'.


For example: a. returns vec4(a.x, a.x, a.x, a.x);
a.x01z returns vec4(a.x, a.0, a.1, a.z);

The only thing I don't want  to implement from the GLSL spec is 
those non-contigous swizzle assignments like:

a.zyx = vec3(1,2,3) ***
but
a.xyz = vec3(1,2,3) should work.

*** maybe with a struct that refers to the original vector and 
the swizzle code it could be also possible. :D


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread realhet via Digitalmars-d-learn

On Sunday, 20 September 2020 at 17:08:49 UTC, realhet wrote:
On Sunday, 20 September 2020 at 16:18:19 UTC, Steven 
Schveighoffer wrote:

On 9/20/20 11:52 AM, realhet wrote:
On Sunday, 20 September 2020 at 14:54:09 UTC, Steven 
Schveighoffer wrote:

On 9/20/20 9:30 AM, realhet wrote:

Yeah, I think this might work.


https://gist.github.com/run-dlang/4b4d4de81c20a082d72eb61307db2946

Here's a little example.
In the main() there are the requirements.
Below that is the implementation. If it is ugly, please tell me 
how to make it prettier :D


Once I was able to make the compiler for a really long time, so I 
know it is rather templates than explicit mixins. All the 
swizzles that cover a contiguous area are mixed in though: in a 4 
element vector it is: only a few elements: "x", "y", "z", "w", 
"xy", "yz", "zw", "xyz", "yzw", "xyzw", "r", "g", "b", "a", "rg", 
"gb", "ba", "rgb", "gba", "rgba", "s", "t", "p", "q", "st", "tp", 
"pq", "stp", "tpq", "stpq"

For everything there is opDispatch.


Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread realhet via Digitalmars-d-learn

Hi,

struct S{
  int[2] array;

  ref  x()   { return array[0]; }
  auto x() const { return array[0]; }
}

If there a way to write the function 'x' into one function, not 2 
overloads.


I tried auto/const/ref mindlessly :D, also remembered 'inout', 
but obviously those weren't solve the problem.


(This is going to be a swizzling 'system' that mimics GLSL, later 
I will make a template that takes 'x'as a template parameter, 
just wondering that the support for const and non-cons can be 
done easier.)


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread realhet via Digitalmars-d-learn

On Sunday, 20 September 2020 at 13:30:36 UTC, realhet wrote:

Hi,


More specifically:

struct S{
int[2] array;

ref swizzle(string code)(){
 static if(code=="x") return array[0];
else static if(code=="y") return array[1];
else static assert("Unhandled");
}
}

To make this work for const/immutable structs, I have to make 
another function with the header: auto swizzle(string code)() 
const{ copy or mixin the whole thing again... }


Maybe there is a language feature for this, like "auto ref" or 
"inout"?


Thank you!


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread realhet via Digitalmars-d-learn

On Sunday, 20 September 2020 at 15:52:49 UTC, realhet wrote:
On Sunday, 20 September 2020 at 14:54:09 UTC, Steven 
Schveighoffer wrote:

On 9/20/20 9:30 AM, realhet wrote:


I managed to do the constant swizzles and it seems so elegant:

  auto opDispatch(string def)() const
  if(validRvalueSwizzle(def)) //making sure that only the few 
thousand valid swizzles can pass through here

  {
static if(def.startsWith('_')){ //if the swizzle definition 
starts with a number

  return opDispatch!(def[1..$]);
}else{
  Vec!(CT, mixin(def.length)) res;
  static foreach(i, ch; def)
res[i] = mixin(ch);  // ch can be one of xyzw or rgba or 
stpq or 0 or 1.
 // just mix it in using the already 
created lvalue swizzles of (integer consts 01)

  return res;
}
  }

I also have an idea that if I use capital letters, it shoud mean 
negative components. This way importing a 3d vertex could be so 
easy in compile time: rotated = original.xZy -> this is rotated 
90 degrees around the x axis. Just need to add an uppercase check.


Never dared to go that far in compile time dlang stuff, and I 
love it. :D Amazing language!


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread realhet via Digitalmars-d-learn
On Sunday, 20 September 2020 at 16:18:19 UTC, Steven 
Schveighoffer wrote:

On 9/20/20 11:52 AM, realhet wrote:
On Sunday, 20 September 2020 at 14:54:09 UTC, Steven 
Schveighoffer wrote:

On 9/20/20 9:30 AM, realhet wrote:

Yeah, I think this might work.

-Steve


That would be a 3rd category out if 4 in total:
- ref for the contiguous subVectors (vec4.init.yz is a vec2)
- const for the complicated ones (vec4.init.z0 is a vec2, 2nd 
component is 0)
- swizzled struct of a referenced vector: (vec4 a; a.yx is a 
struct that links to the original 'a' by reference and know it 
has to swap x and y).
- everything else that can contain any vector component at any 
place including constants 0 and 1. I've learned this kind of 
swizzling in the good old CAL/AMD_IL times.


Swizzled struct is on the righr: then it should be implicitly 
casted when assigning it to the left to a vector. I gotta learn 
that too.


In GLSL this behavior is implemented deeply in the compiler. I'm 
so happy in D it seems also possible :D


What kind of mangling has the LDC2 -X JsonFile "deco" field?

2020-09-16 Thread realhet via Digitalmars-d-learn

Hello,

I'm trying to get information from the JsonFile produced by LDC2, 
but having no clue how to decode this:


For example:
header: KeywordCat kwCatOf(int k)
  "deco" : "FAyaZE3het8keywords10KeywordCat",

The "deco" field contains the full name of the return type 
het.keywords.KeywordCat, but in front of that I don't know how to 
decode that "FAyaZE".


Also this is how a string return type is encoded: "FiZAya"

I tried std.demangle and and online GCC demangler, but no luck.

Anyone can help me telling how to decode these please?

Thank you in advance!


Catching OS Exceptions in Windows using LDC

2020-07-04 Thread realhet via Digitalmars-d-learn

Hi,

I'd like to catch the OS Exceptions including:

- access violation
- int 3
- invalid opcode
etc.

The default behavior is that when these events happen, the 
program immediately exits with some negative exit code.


It was not a problem on other systems like: MSVC or Delphi, but 
on LDC these events are completely ignored.


It would be very useful to catch these errors inside and have the 
opportunity to handle it whatever is the best: application exit, 
save important data, ignore.


I've already found a solution from Adam D. Ruppe, but that's for 
Linux for the Access Violation case. But is there a similar thing 
for Windows as well?


PS: I do believe rely on AccessViolation to avoid buffer overruns 
is really useless and unsecure. But it would be so much help for 
me for developing/debugging my programs.


Thank You!


Re: Catching OS Exceptions in Windows using LDC

2020-07-07 Thread realhet via Digitalmars-d-learn

On Saturday, 4 July 2020 at 14:44:06 UTC, Kagamin wrote:
try 
https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setunhandledexceptionfilter


Thank You, this was the winner for me.
Not just I can catch the OS Exceptions, I can check and alter the 
CPU state and decide to continue execution from an optionally 
modified cpu state, or just stop and show the error.


It needed some work, but this seems the best way for LDC2 Win64.


Re: Making alias of a struct field needs "this".

2020-06-03 Thread realhet via Digitalmars-d-learn
On Tuesday, 2 June 2020 at 20:38:40 UTC, Steven Schveighoffer 
wrote:

On 6/2/20 10:51 AM, realhet wrote:

On Tuesday, 2 June 2020 at 13:10:55 UTC, Paul Backus wrote:

On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:


A month ago I discovered that mixinDeclarations can be used for 
types too:


mixin("int[", 2, "]") a = [5, 6];




Re: Making alias of a struct field needs "this".

2020-06-03 Thread realhet via Digitalmars-d-learn

On Wednesday, 3 June 2020 at 10:11:59 UTC, realhet wrote:
On Tuesday, 2 June 2020 at 20:38:40 UTC, Steven Schveighoffer 
wrote:

On 6/2/20 10:51 AM, realhet wrote:

On Tuesday, 2 June 2020 at 13:10:55 UTC, Paul Backus wrote:

On Tuesday, 2 June 2020 at 09:28:01 UTC, realhet wrote:


mixin("int[", 2, "]") a = mixin([5]) ~ 6;

That's insane :D


Weird behavior with UDAs

2020-06-13 Thread realhet via Digitalmars-d-learn
Hello, I have a problem I can't even understand with the code 
below:


https://run.dlang.io/is/7yXAEA

import std.stdio, std.range, std.algorithm, std.traits, std.meta;

struct UNIFORM{ string name; }

struct A{
int i1;
@UNIFORM() int i2;
@UNIFORM("fuzz") int i3;
@UNIFORM int i4;
}

template getUDA(alias a, U){
  static if(hasUDA!(a, U)) enum getUDA = getUDAs!(a, U)[$-1];
  else enum getUDA = U.init;
}

pragma(msg, getUDA!(A.i1, UNIFORM)); //UNIFORM(null)
pragma(msg, getUDA!(A.i2, UNIFORM)); //UNIFORM(null)
pragma(msg, getUDA!(A.i3, UNIFORM)); //UNIFORM("fuzz");
pragma(msg, getUDA!(A.i4, UNIFORM)); //Error: initializer must be 
an expression, not UNIFORM


struct UNIFORM2{ string name=""; }
struct B{ @UNIFORM2() int i1; }

pragma(msg, getUDA!(B.i1, UNIFORM2)); //UNIFORM("") instead if 
UNIFORM(null)


//

My first question is, how to avoid that error with A.i4?  Why is 
there a difference between @UNIFORM and @UNIFORM(), do the first 
returns a type and the later returns a value?


My second quertion is, why the UNIFORM struct with uninitialized 
string producing UNIFORM(null).
How can be a difference when I say name="", and it's just the 
same as the default string initializer, and then it produce 
UNIFORM("")?


Thank You!



Re: Weird behavior with UDAs

2020-06-13 Thread realhet via Digitalmars-d-learn

On Saturday, 13 June 2020 at 12:55:36 UTC, realhet wrote:

Hello, I have a problem I can't even understand with the code


For the first I realized that an UDA can be a type too, and come 
up with this:


template getUDA(alias a, U){
  enum u = q{ getUDAs!(a, U)[$-1] };
static if(hasUDA!(a, U) && !is(mixin(u)))
  enum getUDA = mixin(u);
else
  enum getUDA = U.init;
}

So I always get an instance of the UDA with the default values.

But the second question is still beyond me:

How can be a string represented with 'null' by default instead on 
`""`. Unless I state it explicitly with name="" ? o.O


Handling referencing class parent instances in a GC friendly way.

2020-11-30 Thread realhet via Digitalmars-d-learn

Hi,

class A{
  A parent;
  A[] items;

  void myDestroy(){
items.each!(i => i.myDestroy);
parent = null;
// after this point I think the GC will release it 
automatically, and it will call ~this() too. Am I right?

  }
}

I have a hierarchy of class instances forward and backward linked 
to its items ant its parent.


What is a proper way to destroy an instance of class A? Is 
calling instance.myDestroy sufficient?


Am I right that this kind of uninitialization MUST not go into 
the ~this() destructor, because of the references the instance is 
holding, the system will never call the ~this()?


Or is there a better way for this type of thing in Dlang?


Thanks in advance!


Re: Handling referencing class parent instances in a GC friendly way.

2020-11-30 Thread realhet via Digitalmars-d-learn
On Monday, 30 November 2020 at 14:36:08 UTC, FeepingCreature 
wrote:

On Monday, 30 November 2020 at 14:33:22 UTC, realhet wrote:
...
Though you may want to do `items = null;` too.


I just forgot 1 of three things, thx for pointing it out.
And I also forget to notify the parent to remove the reference 
from its items list.





Re: Is there a standard function that combines take() and popFrontExactly()

2020-12-14 Thread realhet via Digitalmars-d-learn

On Monday, 14 December 2020 at 14:16:41 UTC, Dukc wrote:

On Friday, 11 December 2020 at 19:07:23 UTC, realhet wrote:
I've just made this unicode wordreplacer function working, but 
It seems not too nice and functional-ish.

Are there ways to make it more simple?



To answer the title, yes there is:



Thanks for ideas!

Yesterday I ended up making this helper funct:
auto fetchFrontExactly(R)(ref R r, size_t n) if(isInputRange!R){
auto res = r.takeExactly(n);
r.popFrontExactly(n);
return res;
}

Now I leaned from you: refRange and take-s ability to pop 
elements from a refRange.

That's what I was needed!

Now the 2 aproach looks like:

string replaceWords(alias fun = isWordChar)(string str, string 
from, string to){

if(1){
auto fetchAndReplace(Tuple!(bool, uint) p){
auto act = refRange().take(p[1]).text;
return p[0] && act==from ? to : act;
}
return str.map!fun
  .group
  .map!fetchAndReplace
  .join;
}else{
string res;
foreach(isWord, len; str.map!fun.group){
auto act = ().refRange.take(len).text;
res ~= (isWord && act==from ? to : act);
}
return(res);
}
}

They are the same thing, but the first looks nicer because it is 
a processing pipe with the state modifying thing extracted to a 
named function (so that's makes the pipe more understandable).
However in the foreach version I can have meaningful parameter 
names: (isWord, len) instead of a tuple.


I don't want to do functional programming just for itself. I'm 
just learning it, and want to understand it better. I already 
found a lot of good uses of it for my tasks and I still discover 
a lot of cool stuff.


Thanks again!


Is there a standard function that combines take() and popFrontExactly()

2020-12-11 Thread realhet via Digitalmars-d-learn

Hi,

I've just made this unicode wordreplacer function working, but It 
seems not too nice and functional-ish.

Are there ways to make it more simple?


import std.stdio, std.range, std.algorithm, std.uni, std.utf, 
std.conv;


bool isWordChar(dchar ch){
return isAlphaNum(ch) || ch=='_';
}

string replaceWords(alias fun = isWordChar)(string str, string 
from, string to){

auto res = appender!string();
auto src = str.byCodePoint;
foreach(isWord, len; str.map!fun.group){
auto act = src.take(len).text;
src.popFrontExactly(len);

res.put(isWord && act==from ? to : act);
}
return(res[]);
}

void main(){
immutable str = "Type=FunctionType Type; éType Type2: Type 
aTypeb Type";

str.replace("Type", "AsmType").writeln;
str.replaceWords("Type", "AsmType").writeln;
}

Thanks in advance!


Re: C++ or D?

2020-11-09 Thread realhet via Digitalmars-d-learn

On Tuesday, 10 November 2020 at 01:00:50 UTC, Mark wrote:

Hi all,

my question would be about using D or not using D.


Here are some things you will NOT get in D:
youtube -> Dconf 2014 Day 2 Keynote: The Last Thing D Needs -- 
Scott Meyers


For example, you will not get neurosis from it, or badly infected 
wounds someone mentioned earlier :D


I also like the fast compile times, and the compile time 
programming, the ability that you can program D in D if you wish.


How to capture a BitFlags type in a function parameter?

2021-01-31 Thread realhet via Digitalmars-d-learn

Hi,

I wan't to process every specialization of the BitFlags struct in 
a function:

So far the best I can come up is this:

  static void stdUI(F)(ref F flags) 
if(F.stringof.startsWith("BitFlags!(")){}


But it's obviously lame.
If I try this way:

  static void stdUI(E, U)(ref BitFlags!(E, U) flags){}

I get a cannot deduce arguments error.

Same error with:
  static void stdUI(E, U, B = BitFlags!(E, U))(ref B flags){}

I'd like to know the Enum type as well.

Thank You for your help in advance!




Re: How to capture a BitFlags type in a function parameter?

2021-01-31 Thread realhet via Digitalmars-d-learn

On Sunday, 31 January 2021 at 14:16:15 UTC, Paul Backus wrote:

On Sunday, 31 January 2021 at 14:04:00 UTC, realhet wrote:

Hi,

static void stdUI(E, Flag!"unsafe" u)(ref BitFlags!(E, u) 
flags) {}


Thank You!

Somehow I forgot I could pass amd match ANY TYPE in the template 
parameters. I'll remember this, thanks!




Re: Is there a nicer way to get the first element or typeof(element).init from a range?

2021-05-30 Thread realhet via Digitalmars-d-learn

On Sunday, 30 May 2021 at 12:16:19 UTC, realhet wrote:


   presets.keys.sort.take(1).get(0);   <-


Oups: after fixing an error and making it compile the solution is 
even uglier:


presets.keys.sort.take(1).array.get(0);


Is there a nicer way to get the first element or typeof(element).init from a range?

2021-05-30 Thread realhet via Digitalmars-d-learn

Hello,

This is my current solution but there must be a better way to do 
it in D


   T get(T)(T[] arr, size_t idx, T def = T.init){
 return idx

array inside a class + alias this + filter -> clears the array.

2021-07-07 Thread realhet via Digitalmars-d-learn

Hi,

I wanted to make a container class that exposes its elements 
using a simple "alias this", but getting weird errors:


I test with the std.algorithm.filter template function.

1. when I use "alias this" on a function that returns a slice, 
making the internal array unreachable, filter just can't compile.
2. when I expose the array as it is, filter deletes the array 
after it returns.


My goal is to make a class, which acts like an array, but also 
having member functions to add/remove/find its items. On top of 
that this class has an owner (a database table thing) too.


Example use-cases:
table.rows.add(...)
table.rows[4]
table.rows.filter!(...).map!(...)


```
import std.stdio, std.range, std.algorithm, std.uni, std.utf, 
std.conv, std.typecons, std.array, std.traits, std.exception, 
std.format, std.random, std.math;


class C{ //must be a class, not a struct
int[] array;

static if(0){
   //BAD: filter cannot deduce from an aliased function
   // that returns a nonref array
  auto getArray(){ return array; }
  alias getArray this;
}else{
  alias array this; //this works
}
}

void main(){
auto c = new C;
c.array = [1, 2];

void wl(){ writeln("len=", c.length); }

//filtering the array explicitly: GOOD
c.array.filter!"true".each!writeln; wl;

//filtering the slice of the alias: GOOD
c.array.filter!"true".each!writeln; wl;

//filtering the alias: BAD -> erases the array
c.filter!"true".each!writeln; wl;
}
```


Thanks in advance.


Re: array inside a class + alias this + filter -> clears the array.

2021-07-07 Thread realhet via Digitalmars-d-learn

On Wednesday, 7 July 2021 at 17:10:01 UTC, Paul Backus wrote:

On Wednesday, 7 July 2021 at 16:20:29 UTC, realhet wrote:



int[] opIndex() { return array; }


Thx, I didn't know about this type of opSlice override. It works 
nicely.


Now I have these choices:
- write [] everywhere to access the containers.
- write nothing extra to access the containers but put the 
container operations one level higher and select the container 
for those based on a dummy struct.


Like going from:
```
db.entities.add("Entity01");
to
db.add(entity("Entity01"));   //struct entity{ string name; }
```

Currently I have both ways plus your solution for the range 
access.


Gotta experience with it to choose.

Thanks again! I will remember that common container rule from now 
on.


Re: Voldemort type "this" pointer

2021-04-22 Thread realhet via Digitalmars-d-learn

On Wednesday, 21 April 2021 at 15:53:59 UTC, Ali Çehreli wrote:

On 4/21/21 8:37 AM, realhet wrote:

On Wednesday, 21 April 2021 at 10:47:08 UTC, Mike Parker wrote:

On Wednesday, 21 April 2021 at 10:00:51 UTC, realhet wrote:

It has access to the context of its enclosing scope (via an 
added hidden field).


Thanks!

So it is unsafe to return a non-static nested struct from a 
function. But it is useful to pass it forward into other 
functions.


Not at all. (D is good at preventing such bugs anyway.)

The local context that the nested struct object uses becomes 
the context of that object.


Wow, this information is really out of the box for me. I have one 
misconception less now.
(I never used a language with GC before and this thing requires a 
GC for sure.)


/---
auto uiDeclare(void delegate() fun){
struct UiObject{
//void delegate() fun; <- not needed, it captures fun in 
the params

void render(){ fun(); }
}
return UiObject();
}

long rec(long a, long c){ return aauto b = [ uiDeclare({ writeln("boop", a); }), uiDeclare({ 
writeln("boop", a+1); })];

rec(0, 123456); // destroy the stack to make sure
b.each!"a.render";
}

Indeed it's not using the stack. And it also works when a 
delegates captures its scope.
In my immediate GUI interface I'm using delegates all the time 
with the my misconception of I only allowed to call them from 
inside the function I passed them into.
For example: Row({ Text(clBlue, "Hello"); 
Img(`pictures\pic1.jpg`); }); will call the delegate from inside, 
not save it for later use.


And if I save the delegate inside the Row() function (I mark UI 
generating functions with a capital letter), it is protected from 
the GC and can be used later in rendering time... Too bad, the 
data it uses at that later moment is possibly changed already.


Anyways, I've learned a lot now. Thank you!


lockstep works with .each, but fails with .map

2021-03-05 Thread realhet via Digitalmars-d-learn

Hi
What am I doing wrong here?

import std.stdio, std.range, std.algorithm, std.uni, std.utf, 
std.conv, std.typecons, std.array;


auto SE(A, B)(in A a, in B b){
return (a-b)^^2;
}

void main(){
auto a = [1, 2, 3], b = [1, 1, 1];
lockstep(a, b, StoppingPolicy.requireSameLength).each!((a, 
b){ writeln(SE(a, b)); });
lockstep(a, b, StoppingPolicy.requireSameLength).map !((a, 
b){ return  SE(a, b) ; }).each!writeln;  <- error here

}

The error:
map(Range)(Range r)
  with Range = Lockstep!(int[], int[])
  must satisfy the following constraint:
   isInputRange!(Unqual!Range)

Why it works with each (or foreach), but not with map? o.O

I just wanted to make a Sum of squared errors function.

Thanks in advance!


  1   2   >