Re: What is the best way to refer to itself when obtaining Substring of a literal?
On Friday, 24 April 2020 at 22:24:34 UTC, Marcone wrote: I don't want to use lambda. I don't want create variable. What is the best way to refer to itself when obtaining Substring withou using lambda and without create variable? example: writeln("Hello Word!"[x.indexOf(" "), $]); Maybe u want this? import std.algorithm: find; import std.stdio: writeln; "Hello World".find(" ").writeln;
Re: Strip Unused Symbols Ldc + Windows
On Saturday, 21 March 2020 at 18:01:55 UTC, kinke wrote: On Saturday, 21 March 2020 at 17:33:21 UTC, SrMordred wrote: Hmm, ok, my question is in fact relate to this kind of thing: https://godbolt.org/z/NGjyyx Why int example.add(int, int): its still on the binary when all u need is alredy optimized to main: mov eax, 30 ret ? You're inspecting an object file, before any linker and symbol stripping is involved. Oh, i thought that the symbol stripping was before linker!, my bad, thanks!
Re: Strip Unused Symbols Ldc + Windows
On Saturday, 21 March 2020 at 15:53:53 UTC, kinke wrote: On Saturday, 21 March 2020 at 01:54:00 UTC, SrMordred wrote: Someone knows how to strip unused symbols on final binary using ldc on windows ? i found this about this topic: https://forum.dlang.org/post/yvmnkvzgoxhcfavja...@forum.dlang.org that uses --gc-sections and --version-script but this options are not avaliable in windows lld-link That was about ELF symbol visibility and doesn't apply to Windows at all. - The symbols are stripped by default for Windows targets (/OPT:REF for MS linker/LLD). You can cross-check by disabling via `-disable-linker-strip-dead`. Hmm, ok, my question is in fact relate to this kind of thing: https://godbolt.org/z/NGjyyx Why int example.add(int, int): its still on the binary when all u need is alredy optimized to main: mov eax, 30 ret ?
Strip Unused Symbols Ldc + Windows
Someone knows how to strip unused symbols on final binary using ldc on windows ? i found this about this topic: https://forum.dlang.org/post/yvmnkvzgoxhcfavja...@forum.dlang.org that uses --gc-sections and --version-script but this options are not avaliable in windows lld-link
External .o sources + BetterC : undefined symbol: __chkstk
I got undefined symbol: __chkstk when using some external .o sources ( compile with clang ) + betterC flag. I thought that __chkstk was present on ntdll.lib, so i added manually as a lib, but still didn´t work. How can i solve this? (it must be another lib that D includes since it works without the betterC flag.)
Re: BetterC + startsWith
The issue is that strings aren't input ranges in betterC [1], due to autodecoding. Normally you'd work around this using std.utf.byCodeUnit, but that's currently broken, because std.utf attempts to import core.exception.UnicodeException from druntime at module scope [2], causing any betterC program that imports std.utf to fail compilation. So, for now, I think the best you can do is probably to copy-paste byCodeUnit into its own source file, and use that until std.utf is fixed. [1] https://issues.dlang.org/show_bug.cgi?id=20139 [2] https://github.com/dlang/phobos/blob/7a656e09d23507d0c404dabaa2c440a45e7c753d/std/utf.d#L65 Oh right, thanks! Its the third time that autodecoding bite me in betterC and i always forgot of the possibility.
BetterC + startsWith
//-betterC import core.stdc.stdio; import std.algorithm; void main(){ printf( "%d\n",startsWith("a","b") ); } //Fails to compile with betterC, dmd/ldc2 last versions. Any reason for not work with betterC or should i file the issue ? (Find this on a bindbc lib, so i think that it may have worked previously)
Re: dub build doesn't work
On Tuesday, 22 October 2019 at 22:14:02 UTC, OiseuKodeur wrote: Hello, i am having a problem with dub build with this project https://github.com/OiseauKodeur/cervelet/tree/master/source when i try to compile everything go well but when i click to run the .exe it give my an error missing msvcr100.dll, but with rdmd the program run fine I got into this recently too. I have the latest VS and redistributable packages installed and was unable to find msvcr100.dll too. Which is very odd. Lucky I found it on another software installed on my PC.
Re: My dialogue code is not working as it should!
On Sunday, 20 October 2019 at 08:41:19 UTC, TodNaz wrote: Hello! I can’t understand ... My dialogue code is not working as it should! He must, if the texture does not exceed the maximum value, add a character, otherwise go to a new line until the text ends. But he constantly makes the transition to a new line. Either I'm stupid, or something is wrong. If something is not clear, knock! Preferably by mail: tod@ya.ru Code: https://pastebin.com/tDtUnjYu Sorry but I think no one here will just take a look at your project and search where the problem is. If you could create a minimal code that shows the code that behaves differently of what u expect, i´m sure that everyone here will be glad to help out :)
Re: Functional Programming in D
https://garden.dlang.io/
Re: What is "dual-context" ?
On Friday, 13 September 2019 at 04:23:47 UTC, Paul Backus wrote: On Friday, 13 September 2019 at 02:49:33 UTC, SrMordred wrote: [...] "Dual context" is the compiler feature that allows you to pass delegates as template arguments to member functions. For a long time, limitations in the frontend made this impossible [1]. It was recently fixed in dmd [2], but the fix hasn't made it into ldc yet [3], so code that takes advantage of this feature is currently dmd-only. [...] Nice!, Thanks for the explanation and workaround :)
What is "dual-context" ?
source\app.d(37,10): Error: function `app.main.match!((some) => print(some), (none) => print("none")).match` requires a dual-context, which is not yet supported by LDC I was playing with my home made "sumtypes". The code below works fine in dmd, but in ldc it triggers that error. x.match!(some => print(some), none => print("none")); What exactly is this "dual-context"?
Re: hasElaborateCopyConstructor bug?
On Sunday, 2 June 2019 at 04:02:08 UTC, Paul Backus wrote: On Saturday, 1 June 2019 at 23:29:08 UTC, SrMordred wrote: On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote: On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote: Haven't tested it extensively, so use at your own risk, but it should work. Nice, thanks! Atm i'm using __traits(compiles, instance.__ctor(other) ) but your solution may be the right way of doing it :)
Re: hasElaborateCopyConstructor bug?
On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote: On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote: hasElaborateCopyConstructor checks if the type defines a postblit[0]. Yes, I know this. But since dmd 2.086 we have copy ctors: https://dlang.org/changelog/2.086.0.html#copy_constructor And its seem logical that if I want a trait that check if copy ctors exists I will use this name 'hasElaborateCopyConstructor' So it looks like a naming issue for me. Unless postblits will be eventually replaced by copy ctors.
hasElaborateCopyConstructor bug?
import std.traits; struct T { this(ref return scope T other){} } pragma(msg, hasElaborateCopyConstructor!T); //false
Re: Calling copyctor manually
On Saturday, 1 June 2019 at 19:10:36 UTC, Paul Backus wrote: On Saturday, 1 June 2019 at 02:27:36 UTC, SrMordred wrote: void main() { T a; T b; a.__ctor(b); } https://run.dlang.io/is/NeioBs Thanks! The most obvious way i didn´t think :P
Calling copyctor manually
Its possible to call copyctor manually without calling dtor? ex, what i did before: struct T{ ~this(){ writeln("DTOR"); } this(this){ writeln("POSTBLIT"); } } T a; T b; memcpy(,,T.sizeof); a.__postblit; /* output: POSTBLIT DTOR DTOR */ With copy ctors, not sure what to do. struct T{ ~this(){ writeln("DTOR"); } this(ref return scope T self){ writeln("COPYCTOR"); } } T a; T b; memcpy(,,T.sizeof); a.opAssign(b); //??? //same as a = b; /* output: COPYCTOR DTOR DTOR DTOR */ I want something like '.__xcopyctor'
Re: Dlang + emscripten
On Thursday, 16 May 2019 at 19:27:15 UTC, Dukc wrote: On Thursday, 16 May 2019 at 18:23:12 UTC, SrMordred wrote: [...] Nice will take a look on this two, thanks :)
Dlang + emscripten
I´m following this link to build d+sdl2+emscripten on web: https://theartofmachinery.com/2018/12/20/emscripten_d.html And, i´m was able to compile but i get the warnings warning: Linking two modules of different data layouts / target triples even when I compile using x86. So i´m not sure if this is a LDC or Emscripten issue. Someone is also exploring emscripten?
Re: Emulating DLL
On Tuesday, 19 March 2019 at 19:50:15 UTC, Craig wrote: Take a look at my lib, its a simple hot-reload external dll lib: https://github.com/SrMordred/reloaded I did´nt use it extensively, but its simple enough to be tweaked at your own need :)
Re: isSame/TemplateOf bug?
On Tuesday, 19 February 2019 at 23:03:37 UTC, Paul Backus wrote: On Tuesday, 19 February 2019 at 22:43:25 UTC, SrMordred wrote: import std.traits; import std.stdio; struct Test(T) { this(T)( auto ref T value ) { writeln( TemplateOf!(typeof(value)).stringof); writeln( __traits(isSame, TemplateOf!(typeof(value)), Test) ); } } void main(){ auto value = Test!int(Test!int()); writeln( TemplateOf!(typeof(value)).stringof); writeln( __traits(isSame, TemplateOf!(typeof(value)), Test) ); } //output: Test(T) false Test(T) true Inside a templated struct, the name of the template, by itself, actually refers to the current instantiation. So when you write `Test` in your __traits(isSame) test, the compiler interprets it as `Test!T`. True! writeln(Test.stringof) inside the struct give me Test!int. Thanks! Little unexpected D dark corner :P
isSame/TemplateOf bug?
import std.traits; import std.stdio; struct Test(T) { this(T)( auto ref T value ) { writeln( TemplateOf!(typeof(value)).stringof); writeln( __traits(isSame, TemplateOf!(typeof(value)), Test) ); } } void main(){ auto value = Test!int(Test!int()); writeln( TemplateOf!(typeof(value)).stringof); writeln( __traits(isSame, TemplateOf!(typeof(value)), Test) ); } //output: Test(T) false Test(T) true
Re: dub ldc error _d_array_slice_copy
On Monday, 18 February 2019 at 23:40:20 UTC, kinke wrote: On Monday, 18 February 2019 at 19:10:50 UTC, SrMordred wrote: dub --compiler=ldc2 //app.d:4: error: undefined reference to '_d_array_slice_copy' Dub has nothing to do with it, it's the -betterC flag, and LDC expecting that druntime function to be available for slice copies. Quick workaround: add a manual version (here without any checks) somewhere in your code: extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz) { import ldc.intrinsics : llvm_memcpy; llvm_memcpy!size_t(dst, src, dstlen * elemsz, 0); } Thanks, I discovered this workaround too :) But I dont get it: -betterC aren't supoused to be D without any druntime? Why it is searching for this function?
Re: dub ldc error _d_array_slice_copy
On Monday, 18 February 2019 at 19:14:42 UTC, SrMordred wrote: oh, and: DUB version 1.13.0, built on Feb 17 2019 LDC - the LLVM D compiler (1.14.0): based on DMD v2.084.1 and LLVM 7.0.1 Sorry, both give the same error, the problem is related to -betterC flag (which i forgot to add on first compile example), but stil..
Re: dub ldc error _d_array_slice_copy
oh, and: DUB version 1.13.0, built on Feb 17 2019 LDC - the LLVM D compiler (1.14.0): based on DMD v2.084.1 and LLVM 7.0.1
dub ldc error _d_array_slice_copy
On ubuntu: void test(size_t l) { char* a; a[0 .. l] = a[0 .. l]; } extern(C) void main(){ test(0); } ldc2 source/app.d //compiles dub --compiler=ldc2 //app.d:4: error: undefined reference to '_d_array_slice_copy'
Re: Is there a nice syntax to achieve optional named parameters?
On Thursday, 17 January 2019 at 12:11:02 UTC, Matheus wrote: foo(alias x){} foo("a"); foo(1); 'x' will be string one time and integer another? Or there is something that I'm missing. Matheus. Yes, but there is a mistake there: alias is part of the template: foo(alias x)(){} //note extra parens than u call like an template: foo!"a"; //equivalent = foo!("a")(); foo!1;
Re: Is there a nice syntax to achieve optional named parameters?
On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote: As an example let's say I have a type 'Window' that represents a win32 window. I'd like to be able to construct an instance of the type with some optional parameters that default to some reasonable settings and create the underlying win32 window. I'd ideally like some syntax like this :- auto window = Window(title = "My Window", width = 1000, fullscreen = true); Assume that title, width, fullscreen are optional and if not specified there are defaults to use. And that there are many other settings than just these 3 that I've chosen to just use the default here. I know that I can't do it like this is D but what is the best way to achieve this kind of thing? I can add properties and then do a specific "create" function to create the underlying win32 window once I'm done but that seems ugly. auto window = Window(); window.title = "My Window"; window.width = 1000; window.create(); This is ok, but I'm not so keen on separating the creation and construction like this. Is there a better way that's not ugly? Let me throw this idea here: struct Config { string title; int width; } struct Window { this(Config config) { //use static foreach magic to set everything :P } } auto NewWindow( alias code )() { mixin("Config config = {"~code~"};"); return Window(config); } //usage: auto a = NewWindow!q{ title : "MainTitle" }; auto b = NewWindow!q{ title : "MainTitle", width : 800 }; auto c = NewWindow!q{ width : 1000 }; auto d = NewWindow!q{}; :)
Re: What's that 'q' before '{' in this code?
On Tuesday, 15 January 2019 at 17:52:35 UTC, Machine Code wrote: https://github.com/dlang/dmd/blob/master/src/dmd/compiler.d#L75 https://dlang.org/spec/lex.html#token_strings :)
Bug or expected?
size_t[2] a; size_t[2] b; auto x = a[] & b[]; //array operation without destination memory not allowed size_t[2] y = a[] & b[]; // fine
Re: BetterC + Windows + setjmp longjmp
Ok, after a better look at the sources I finally got it: setjmp is a macro. the true function signature is "int _setjmp(jmp_buf, void*)" the void* is the current function address which in mingw sources are capture by "__builtin_frame_address(0)". And I did´t look yet to see if Dlang have an equivalent. but calling _setjmp(jmp_buf, null); the simple examples are working :)
Re: BetterC + Windows + setjmp longjmp
On Wednesday, 19 September 2018 at 11:12:41 UTC, Diederik de Groot wrote: On Wednesday, 19 September 2018 at 11:06:23 UTC, Diederik de Groot wrote: On Tuesday, 18 September 2018 at 19:45:18 UTC, SrMordred wrote: Only the exact size of the jmp_buf is important (not the details about the content). We only call a function with it, we never look inside. I don't own any windows machines so had to use these references (and could not test anything): - WinSDK10: goo.gl/m9DjZt - MARS: goo.gl/Qoc6g2 Code above does not yet cover the Mars case, but the i386 sizes should be the same. Please Note: setjmp/longjmp should only be used in "@system + @nogc + nothrow / -betterC" code. g++ and clang give me sizeof = 256. dmc give me 64. I tried all this sizes and other, but still crashes.
Re: BetterC + Windows + setjmp longjmp
On Tuesday, 18 September 2018 at 20:01:48 UTC, SrMordred wrote: longjmp is crashing so may be related to the struct declaration. Well just found a thread of the same problem, just that in my case with 64x crashes too. https://forum.dlang.org/post/mmxwhdypncaeikknl...@forum.dlang.org
Re: BetterC + Windows + setjmp longjmp
longjmp is crashing so may be related to the struct declaration.
Re: BetterC + Windows + setjmp longjmp
On Tuesday, 18 September 2018 at 03:09:18 UTC, Mike Parker wrote: On Tuesday, 18 September 2018 at 00:24:23 UTC, SrMordred wrote: Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after. I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik. setjmp/longjmp are available on windows (image loaders using libpng, lua, quake3, and lots of old C code make use of them): https://msdn.microsoft.com/en-us/library/xe7acxfb.aspx?f=255=-2147217396 https://msdn.microsoft.com/en-us/library/3ye15wsy.aspx You can declare the functions in your own code and they should link just fine. It would be helpful if you also submit a PR to add them to DRuntime for Windows. As for sigaction, a quick search suggests it isn't available (and it doesn't show up in MSDN): https://stackoverflow.com/questions/32389905/sigaction-and-porting-linux-code-to-windows I think this may be going beyond my knowledge ;/ (Trying to follow setjmp.h, don´t have experience doing this) enum _SIGSET_NWORDS = (1024 / (8 * (ulong.sizeof))); struct __sigset_t { ulong[_SIGSET_NWORDS] __val; } struct __jmp_buf_tag { long[8] __jmpbuf; int __mask_was_saved; __sigset_t __saved_mask; }; alias __jmp_buf_tag[1] jmp_buf; extern (C) @nogc nothrow int setjmp(ref jmp_buf) ; extern (C) @nogc nothrow void longjmp(ref jmp_buf, int); OK, things linked fine. I´m trying to escape a sigfault with signal + set/longjmp: jmp_buf buf; extern(C) nothrow @nogc void h1(int code) { longjmp(buf, 1); } //main signal(SIGSEGV, ); auto x = setjmp(buf); if(x == 1) ... (go elsewhere) else //forcing some sigfault There are no compilation errors. But my program still just crashes after sigfault. So maybe setjmp/longjmp are not working properly. Or is not possible to escape a crash. Or i completely misunderstood everything :P
Re: BetterC + Windows + setjmp longjmp
On Tuesday, 18 September 2018 at 00:12:35 UTC, Diederik de Groot wrote: On Monday, 17 September 2018 at 23:44:41 UTC, SrMordred wrote: [...] You can use core.stdc.signal nothrow @nogc @system sigfn_t signal(SIGSEGV, sigfn_t func) To catch the signal With a handler signature of: enum void function(int) nothrow @nogc @system SIG_ERR; [...] Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after. I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik.
BetterC + Windows + setjmp longjmp
Its possible to use setjmp/longjmp on windows? Or, to be straight to my problem: its possible to continue execution after a SIGSEGV(or any other failure/signal) with betterC and windows?
Re: array to string functional?
On Friday, 14 September 2018 at 19:44:37 UTC, berni wrote: a) I've got an int[] which contains only 0 und 1. And I want to end with a string, containing 0 and 1. So [1,1,0,1,0,1] should become "110101". Of course I can do this with a loop and ~. But I think it should be doable with functional style, which is something I would like to understand better. Can anyone help me here? (I think a.map!(a=>to!char(a+'0')) does the trick, but is this good style or is there a better way?) b) After having this I'd like to split this resulting string into chunks of a fixed length, e.g. length 4, so "110101" from above should become ["1101","01"]. Again, is it possible to do that with functional style? Probably chunks from std.range might help here, but I don't get it to work. All in all, can you fill in the magic functional chain below? auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; auto result = magic functional chain here :-) assert(result==["1011","1010","","0"]); What you want is std.range.chunks auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; a.map!(to!string) .join("") .chunks(4) .map!(to!string) //don´t know why the chunks are not already strings at this point ;/ .writeln;
Re: hasAliasing with nested static array bug ?
On Thursday, 6 September 2018 at 07:37:11 UTC, Simen Kjærås wrote: On Wednesday, 5 September 2018 at 22:35:16 UTC, SrMordred wrote: https://run.dlang.io/is/TOTsL4 Yup, that's a bug. Reduced example: struct S { int*[1] arr; } import std.traits : hasAliasing; static assert(hasAliasing!S); Issue filed: https://issues.dlang.org/show_bug.cgi?id=19228 Pull request: https://github.com/dlang/phobos/pull/6694 -- Simen Nice, thanks :)
hasAliasing with nested static array bug ?
https://run.dlang.io/is/TOTsL4
C++ GLM(OpenGL Mathematics) D Equivalent.
Most C++ game related projects uses GLM as they default math/vector lib (even if not using opengl). In D we have (that I found): gfm.math - https://github.com/d-gamedev-team/gfm dlib.math - https://github.com/gecko0307/dlib Gl3n - https://github.com/Dav1dde/gl3n But i'm not sure which to pick. Can someone point me out some reasons to use one over the other? (or show some differences) I´m expecting something of equivalent functions and performance as c++ glm. Thank you!
Re: How to use LLD linker?
Well, since its VS 2017 installer, eventually I hit all the components needed to install it properly. Now its working. Thanks 0xEAB for the tip about the Windows SDK too :)
Re: How to use LLD linker?
Delete everything, installed everything again, the installation failed to set the proper PATH to MS link.exe, so i put it by hand and now get: fatal error LNK1104: cannot open file 'libcmt.lib' Frustrating.
Re: How to use LLD linker?
On Friday, 6 July 2018 at 19:36:05 UTC, 0xEAB wrote: On Friday, 6 July 2018 at 03:48:04 UTC, SrMordred wrote: Well I just installed the VS 2017 to try the ldc and get (maybe) the same error. You didn't forget to install the Windows SDK with it, did you? Yep I forgot xD It fixed the PATHs but still getting this: libcmt.lib(chkstk.obj) : fatal error LNK1112: module machine type 'X86' conflicts with target machine type 'x64' which i´m trying to solve now.
Re: How to use LLD linker?
On Friday, 6 July 2018 at 10:55:47 UTC, Rainer Schuetze wrote: On 06/07/2018 05:48, SrMordred wrote: [...] The problem is that the Digital Mars linker is called but the Microsoft linker is run, because they share the same name link.exe. For dmd/x64/32mscoff or LDC in general the latter is expected to be used. Usually dmd and ldc know how to find the appropriate one, but dub might just expect it to be found through the PATH environment variable. So, try to set your PATH so that the MS linker is found first. Yep, this is the way, but i could make it work yet. The PATH works, but i get errors relate to libs, even running vcvarsall.bat. Thats bizarre since its a fresh intallation of VS. It used to work, not sure what happened. Anyway i'll give up by now and try another time. I thought that LDC removed this VS dependecy.
Re: How to use LLD linker?
On Saturday, 30 June 2018 at 10:48:49 UTC, Suliman wrote: Correct me if I am wrong, but I have read news that dmd now can be used without C++ Build Tools. I trying to build simple project. And getting Error: Warning: no Visual C++ installation detected OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename ... Error: C:\D\dmd2\windows\bin\link.exe failed with status: 1 ldc2 failed with exit code 1. Same with dmd. How to use LLD linker? Well I just installed the VS 2017 to try the ldc and get (maybe) the same error. dub run --config=application --arch=x86_64 --build=debug --compiler=ldc2 Performing "debug" build using ldc2 for x86_64. lib ~master: building configuration "application"... OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename /NOLOGO /DEBUG /OPT:REF /OPT:ICF /DEFAULTLIB:libcmt /DEFAULTLIB:libvcruntime "/OUT:.dub\build\application-debug-windows-x86_64-ldc_2081-FC0CCB721F0C7E0D58B93FB1E50E3401\lib.exe" ".dub\obj\lib.obj" "d:\ldc2\lib\ldc_rt.builtins.lib" /LIBPATH:d:/ldc2/bin/../lib phobos2-ldc.lib druntime-ldc.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ^ Error: d:\D\dmd2\windows\bin\link.exe failed with status: 1 ldc2 failed with exit code 1.
Re: CustomString and string constraints
On Tuesday, 26 June 2018 at 22:16:28 UTC, Jonathan M Davis wrote: If what you're asking is whether it's possible for a template constraint that uses something like isSomeString will ever match a user-defined type, then the answer is no. Thats exactly what I wanted xD. My idea was that if you can make custom array types that operate with phobos lib(via some implicit conversions) then there "should" have a way to do that with strings, but I understood the issues that you explained. Thanks!
CustomString and string constraints
Is possible to make a Custom Struct String work for D string constraints? eg: struct MyString { char[] arr; alias arr this; } void getString( char[] str ){} MyString().split(";"); //oops, type mismatch getString( MyString() ); //fine, implicit conversion isSomeString!(char[]).writeln; //true isSomeString!(MyString).writeln; //false
Re: Static Array Idiom not working anymore.
On Tuesday, 12 June 2018 at 16:27:50 UTC, SrMordred wrote: On Tuesday, 12 June 2018 at 15:39:10 UTC, Steven Schveighoffer wrote: Essentially what you had originally was a memory corruption bug (yes, even before the deprecation happened). Oops , that bad. Well, not anymore ;)
Re: Static Array Idiom not working anymore.
On Tuesday, 12 June 2018 at 15:39:10 UTC, Steven Schveighoffer wrote: Essentially what you had originally was a memory corruption bug (yes, even before the deprecation happened). Oops , that bad.
Static Array Idiom not working anymore.
this idiom for creating static array used to work, but they are failing now. What changed and whats the alternative? (from https://p0nce.github.io/d-idioms/#@nogc-Array-Literals:-Breaking-the-Limits) T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow @nogc @safe { return array; } void main() @nogc { int[] myDynamicArray = [1, 2, 3].s; // Slice that static array which is on stack } //output: Deprecation: slice of static array temporary returned by s([1, 2, 3]) assigned to longer lived variable myDynamicArray
Re: delegates and functions
a => { return 2*a; } /\ \ / || \ / ||\ / || \ / || \ / This is \ / function \ This is definition of delegate definition \ so you have a function that returns delegate. ``` it's like a => a => 2*a; or (a){ return () { return 2*a; } I believe that a lot of other languages work differently, so when their knowledge are transposed to D, people get confused at first. Eg. in JS: x = x => x * 2; x = x =>{ return x * 2; } //equivalent
Re: Why char[] is not @nogc on this case
Because arrays of char and wchar are treated as ranges of dchar. That part that I didnt know, thanks! :)
Re: Why char[] is not @nogc on this case
On Friday, 25 May 2018 at 00:04:10 UTC, Adam D. Ruppe wrote: On Thursday, 24 May 2018 at 23:55:24 UTC, SrMordred wrote: //Error: @nogc delegate onlineapp.main.__lambda1 cannot call non-@nogc function std.range.chain!(char[], char[]).chain.Result.front Why? phobos automatically decodes utf8 into dchars. This can throw a new utf exception. Oh its the utf8 decode thing. I forgot about it. I thought that it only decodes when using strings and dchars. Thanks!
Why char[] is not @nogc on this case
int[] a; int[] b; ()@nogc { foreach(v ; chain( a,b ) ) printf("%d\n", v); }(); //Ok, everything fine; char[] a; char[] b; ()@nogc { foreach(v ; chain( a,b ) ) printf("%c\n", v); }(); //Error: @nogc delegate onlineapp.main.__lambda1 cannot call non-@nogc function std.range.chain!(char[], char[]).chain.Result.front Why?
Re: UFCS syntax I never saw before.
"%s %s".writefln = ("foo".tuple = "bar").expand; lol
Re: UFCS syntax I never saw before.
Right, so this should´n be working I think. struct SomeStruct { void foo(int); } SomeStruct s; s.foo = 10; I thought that only with @property this will work.
UFCS syntax I never saw before.
After all this time I saw this: writeln = iota = 5; what?? I never saw that before! This is interesting, there is something useful that i can do with this kind of call?
Re: property += operator
On Thursday, 10 May 2018 at 19:41:41 UTC, Dlang User wrote: On 5/10/2018 1:43 PM, SrMordred wrote: [...] I am relatively new to D and I was under the impression that that was a limitation of @property functions. But, re-reading the language reference, it gave this example (it returns something from the write property, which seems odd), I modified to add refs, and then it seems to work, but I am not sure if it is correct or not: import std.stdio; struct Foo { @property ref int data() { return m_data; } // read property @property ref int data(int value) { return m_data = value; } // write property private: int m_data; } void main() { Foo f; f.data = 5; f.data++; f.data+= 2; writeln(f.data); } this didn´t work either. note that 'f.data+= 2;' don't call the write property
property += operator
struct T { int x; @property ref X(){ return x; } @property X(int v) { x = v; } } T t; t.X += 10; The setter 'x = v' are not executed because i´m returning the reference of x. And without the 'ref' the compiler complains because 'x' is not a lvalue. Any solution to make it work like native arr.length+=10 works? ( I Thought on returning a struct with "+=" operator but it is a strange solution )
Re: Negative index range violation
On Thursday, 22 February 2018 at 02:41:30 UTC, Steven Schveighoffer wrote: Hah! I never thought of doing a slice with negative indexes ;) Maybe is my past of python: arr[-3:] to get the last 3 elements for eg. :)
Re: Negative index range violation
But with a slice negative indexes are never allowed, even on a pointer. youd have to do (c-1)[0 .. 1]; Nice! Thank you both! In D Slice article it says "You can even use negative indexes!" so I thought that the [-1..x] should work too :)
Negative index range violation
string x = "123"; auto c = x.ptr; c++; writeln(c[-1]); // 1 writeln(c[-1..0]); //BOOM Range violation Can I do this / Bug / some mistake ?
Re: multithread/concurrency/parallel methods and performance
On Monday, 19 February 2018 at 05:54:53 UTC, Dmitry Olshansky wrote: The operation is trivial and dataset is rather small. In such cases SIMD with eg array ops is the way to go: result[] = values[] * values2[]; Yes, absolutely right :) I make a simple example to understand why the threads are not scaling in the way i thought they would. I imagine that, if one core work is done in 200ms a 4 core work will be done in 50ms, plus some overhead, since they are working on separate block of memory, without need of sync, and without false sharing, etc (at least I think i don´t have this problem here).
Re: multithread/concurrency/parallel methods and performance
On Monday, 19 February 2018 at 05:49:54 UTC, Nicholas Wilson wrote: As SIZE=1024*1024 (i.e. not much, possibly well within L2 cache for 32bit) it may be that dealing with the concurrency overhead adds a significant amount of overhead. That 'concurrency overhead' is what i´m not getting. Since the array is big, dividing it into 6, 7 cores will not trash L1 since they are very far from each other, right? Or L2 cache trashing is also a problem in this case? _base : 150 ms, 728 μs, and 5 hnsecs _parallel : 120 ms, 78 μs, and 5 hnsecs _concurrency : 134 ms, 787 μs, and 4 hnsecs _thread : 129 ms, 476 μs, and 2 hnsecs Yes, on my PC I was using -release. Yet, 150ms for 1 core. 120-134ms of X cores. Shouldn´t be way faster? I´m trying to understand where the overhead is, and if is possible to get rid of it (perfect thread scaling).
multithread/concurrency/parallel methods and performance
I´m experimenting with threads and related recently. (i´m just started so may be some terrrible mistakes here) With this base work: foreach(i ; 0 .. SIZE) { results[i] = values1[i] * values2[i]; } and then with this 3 others methods: parallel, spawn and Threads. this was my results: _base : 456 ms and 479 us _parallel : 331 ms, 324 us, and 4 hnsecs _concurrency : 367 ms, 348 us, and 2 hnsecs _thread : 369 ms, 565 us, and 3 hnsecs (code here : https://run.dlang.io/is/2pdmmk ) All methods have minor speedup gains. I was expecting a lot more. Since I have 7 cores I expected like below 100ms. I´m not seeing false sharing in this case. or i'm wrong? If someone can expand on this, i'll be grateful. Thanks!
Re: Concurrency send immutable
Nice, thank you!
Re: Concurrency send immutable
On Friday, 24 November 2017 at 12:36:42 UTC, Daniel Kozak wrote: Should print something like this: std.concurrency.OwnerTerminated@std/concurrency.d(223): Owner terminated Yes, it was, I was aware of this and put some sleep after that too. (immutable (int)[] v) OK that parenteshis was the problem, thanks :) But its a little confusing i think, since the syntax for creating the array is different from the syntax on the arguments. and: immutable int[]; immutable (int)[]; immutable (int[]); (differences? what/when use) And other question: When you send immutable data , i'm getting a copied data on the other thread, or its the same data? Like: send(thread1, arr); send(thread2, arr); send(thread3, arr); send(thread4, arr); (multiple copies, or all threads are seeing the same addresses ? )
Re: Concurrency send immutable
On Friday, 24 November 2017 at 12:05:16 UTC, SrMordred wrote: immutable int[] arr = [1,2,3,4,5]; auto t = spawn({ receive( (immutable int[] v) => writeln(v) );}); t.send(arr); whats the problem here? Nothing prints out
Concurrency send immutable
immutable int[] arr = [1,2,3,4,5]; auto t = spawn({ receive( (immutable int[] v) => writeln(v) );}); t.send(arr); whats the problem here?
Re: __traits(compiles , mixin ... )
On Wednesday, 25 October 2017 at 20:04:47 UTC, Adam D. Ruppe wrote: On Wednesday, 25 October 2017 at 19:50:31 UTC, SrMordred wrote: so why this line resolves to false? Because it is illegal to put a statement or declaration inside __traits(compiles). sorry, I should have said that before... even though the mixin can be legal in another context, it won't be in the __traits context due to this: https://dlang.org/spec/traits.html#compiles "Returns a bool true if all of the arguments compile (are semantically correct). The arguments can be symbols, types, or expressions that are syntactically correct. The arguments cannot be statements or declarations. " When there's a closing ;, it is a mixin statement. void F(){} pragma(msg, __traits( compiles, mixin("F();") ) );//false Oh, now thats explains. I thought that a "mixin statement" was equal to the argument type that it compiles to. Thanks!
Re: __traits(compiles , mixin ... )
The semicolon there indicates it is a complete statement that does nothing, and that's no error. so why this line resolves to false? void F(){} pragma(msg, __traits( compiles, mixin("F();") ) );//false
Re: __traits(compiles , mixin ... )
On Wednesday, 25 October 2017 at 19:25:01 UTC, Adam D. Ruppe wrote: On Wednesday, 25 October 2017 at 19:12:02 UTC, SrMordred wrote: Maybe i´m tired already, but whats wrong here: pragma(msg, __traits( compiles, mixin("int x") ) ); You are missing a ; The mixin must compile as a full thing in context. Variable declarations need the ; to be complete. it returns false anyway. void F(){ writeln("inside"); } struct T{} void main() { pragma(msg, __traits( compiles, mixin("int x;") ) );//false pragma(msg, __traits( compiles, mixin("F();") ) );//false pragma(msg, __traits( compiles, mixin("F()") ) );//true mixin( "F();" ); //compiles pragma(msg, __traits( compiles, mixin("T();") ) ); //false pragma(msg, __traits( compiles, mixin("T()") ) ); // true mixin( "T();" ); // Error: `structliteral` has no effect in expression `T()` }
Re: __traits(compiles , mixin ... )
On Wednesday, 25 October 2017 at 19:12:02 UTC, SrMordred wrote: Maybe i´m tired already, but whats wrong here: pragma(msg, __traits( compiles, mixin("int x") ) ); //output: false Or the original case I found: struct T{} pragma(msg, __traits( compiles, T() ) ); //true pragma(msg, __traits( compiles, mixin("T()") ) ); //true mixin( "T();" ); Error: `structliteral` has no effect in expression `T()`
__traits(compiles , mixin ... )
Maybe i´m tired already, but whats wrong here: pragma(msg, __traits( compiles, mixin("int x") ) ); //output: false
Re: splitter string/char different behavior
In order to know where to split, it really has to do it from the front. If it starts from the back, you won't necessarily split in the same places as when iterating from the front, and that would violate how bidirectional ranges are supposed to work (the elements should be the same - just in reverse - if you iterate from the back). That being the case, it makes sense that splitting on a single element would result in a range that was bidirectional, whereas splitting on a range of elements would result in a range that's only a forward range. - Jonathan M Davis Nice! since dropBack is a BidirectionalRange everything make sense now. Thanks everybody! I just think that the error message should be a little better, since I have no idea about the incompatible Range types looking only to the error message. (Dont know if is possible, but anyway.. )
Re: splitter string/char different behavior
For "a.b.c"splitter(x), Range r is a string, r.front is a char. The template can only be instantiated if the predicate function is valid. The predicate function is "a == b". Since r.front is a char, then s must be a type that can be compared with '=='. A string and char cannot be compared with '==', which is why the a valid template instantiation could not be found. Would it be correct to just update the documentation to say "Lazily splits a range using an char as a separator" ? what is it; wchar and dchar too? I notice the example that is there has ' ' as the element. But this works: writeln("a.b.c".splitter(".") );
splitter string/char different behavior
writeln( "a.b.c".splitter('.').dropBack(1) ); //compiles ok writeln( "a.b.c".splitter(".").dropBack(1) ); //error: Error: template std.range.dropBack cannot deduce function from argument types !()(Result, int), candidates are: (...) Hm.. can someone explain whats going on?
Parameters template and ref types
When using Parameters!T there are no difference between ref int and int for eg. I know there is ParameterStorageClassTuple!T but it didt solve my problem: I want to transform any ref Type parameters in Type* like: staticMap!( ref2ptr, Parameters!MyFunc ); //(ref int, int) But then again ref2ptr are called only once for int (for staticMap ref int and int are the same)
Re: OpIndex/OpIndexAssign strange order of execution
void main() { auto s = S(); s["b", "c"] = s["a"]; } Prints a ["b", "c"] Ali I thought about this too, thanks!
Re: OpIndex/OpIndexAssign strange order of execution
On Monday, 18 September 2017 at 15:14:20 UTC, Moritz Maxeiner wrote: On Monday, 18 September 2017 at 15:11:34 UTC, Moritz Maxeiner wrote: gets rewritten to --- t.opIndex("b").opIndexAssign(t["a"].value, "c"); --- Sorry, forgot one level of rewriting: --- t.opIndex("b").opIndexAssign(t.opIndex("a").value, "c"); --- Nice, thanks for the explanation :) This will be a problem for me because in my use case the internal operations of the structs are stack-like manipulations. So in this case t["b"]["c"] = t["a"].value; instead of manipulating the internal stack with "a" then "b" and "c" I got this weird order of "b", "a", "c" messing with the internal stack logic. Well, back to work :)
Re: Looking for instructions on how to make a Derelict library
I used to have a guide to creating "Derelictified" bindings for an older version. I should write one up for the current version. +1
Re: OpIndex/OpIndexAssign strange order of execution
Should I report this as a bug? I tried a C++ equivalent code and it execute in the expected order.
OpIndex/OpIndexAssign strange order of execution
struct Test{ @property int value(){ writeln("property value : ", _value); return _value; } int _value; Test opIndex( string index ) { writeln( "opIndex : index : ", index ); return this; } Test opIndexAssign(int value, string index ) { writeln( "opIndexAssign : value : ", value, " , index : ", index ); this._value = value; return this; } } Test t; t["a"] = 100; t["b"]["c"] = t["a"].value; //OUTPUT: opIndexAssign : index : a , value : 100 opIndex : index : b opIndex : index : a property value : 100 opIndexAssign : index : c , value : 100 //EXPECTED OUTPUT opIndexAssign : index : a , value : 100 opIndex : index : a property value : 100 opIndex : index : b opIndexAssign : index : c , value : 100 Is this right? I find unexpected this mix of operations on left and right side of an equal operator.
Re: SDL and new Thread open two windows
On Saturday, 2 September 2017 at 03:47:24 UTC, Adam D. Ruppe wrote: On Saturday, 2 September 2017 at 03:41:47 UTC, SrMordred wrote: Whats going on , and how to prevent this ? Are you using a static this anywhere? Hm, right. I was constructing the window there. Forgot that static this will execute on all threads. Thanks! Removing the code from "static this" solved. putting "__gshared" also. But "shared" crashes the programs...
SDL and new Thread open two windows
Im using SDL2 with derelict, on ubuntu. Last DMD. When using spawn or new Thread like : spawn( (){ while(true){ Thread.sleep(500.msecs); }); the program open two SDL windows. Whats going on , and how to prevent this ?
Re: -betterC not working
On Wednesday, 30 August 2017 at 22:45:27 UTC, Adam D. Ruppe wrote: On Wednesday, 30 August 2017 at 22:18:07 UTC, SrMordred wrote: DMD64 D Compiler v2.075.1 -betterC as described recently is not yet released. https://dlang.org/changelog/2.076.0_pre.html is where it gets the new behavior, and that isn't scheduled for formal release until the end of the week. (it seriously bothers me that Walter has been advertising this so much when the little bit that is implemented isn't even released yet, and what is implemented is barely usable.) The betterC switch itself is not new, but it does virtually nothing until that latest prerelease compiler. ooops, little missed detail ;) At least its near.
-betterC not working
On Ubuntu: //dub.json { "name": "d_betterc", "dflags" : ["-betterC"] } //source/app.d import std.stdio; extern (C) int main(int argc, char** argv) { int[] x; writeln(x); return 0; } //cmd dub run --config=application --arch=x86_64 --build=debug --compiler=dmd //or dmd -betterC source/app.d app.d Both compiles and run. But it shouldnt. What im doing wrong? (I got another type of errors on windows, but can't replicate it right now) DMD64 D Compiler v2.075.1 DUB version 1.4.1, built on Aug 10 2017
Re: Problem with dtor behavior
On Friday, 28 July 2017 at 16:25:01 UTC, Adam D. Ruppe wrote: On Thursday, 27 July 2017 at 19:19:27 UTC, SrMordred wrote: "auto ref means ref for lvalues, value for rvalues." Iep, my confusion was there. My mind is still wrapped around the rvalue references and move semantics of c++
Re: Problem with dtor behavior
On Friday, 28 July 2017 at 15:49:42 UTC, Moritz Maxeiner wrote: [...] Nice, a bit more clear now, thank you!
Re: Problem with dtor behavior
On Thursday, 27 July 2017 at 20:28:47 UTC, Moritz Maxeiner wrote: On Thursday, 27 July 2017 at 19:19:27 UTC, SrMordred wrote: //D-CODE struct MyStruct{ int id; this(int id){ writeln("ctor"); } ~this(){ writeln("dtor"); } } MyStruct* obj; void push(T)(auto ref T value){ obj[0] = value; } void main() { obj = cast(MyStruct*)malloc( MyStruct.sizeof ); push(MyStruct(1)); } OUTPUT: ctor dtor dtor I didnt expected to see two dtors in D (this destroy any attempt to free resources properly on the destructor). AFAICT it's because opAssign (`obj[0] = value` is an opAssign) creates a temporary struct object (you can see it being destroyed by printing the value of `cast(void*) ` in the destructor). Can someone explain why is this happening and how to achieve the same behavior as c++? Use std.conv.emplace: --- import std.conv : emplace; void push(T)(auto ref T value){ emplace(obj, value); } --- It worked but isnt this odd? like, if I change the push(MyStruct(1)) for obj[0] = MyStruct(1); (which is what I expected in case of compiler inlining for example) the behavior change: OUTPUT: ctor dtor I´m having the feeling that this "auto ref T" don´t have the same behavior that the "T&&" on c++. I find this very strange because if i copy/paste/tweak code from c/c++ on D, and have some kind of malloc/free on the ctor/dtor the code will blow in my face without warning.
Problem with dtor behavior
//D-CODE struct MyStruct{ int id; this(int id){ writeln("ctor"); } ~this(){ writeln("dtor"); } } MyStruct* obj; void push(T)(auto ref T value){ obj[0] = value; } void main() { obj = cast(MyStruct*)malloc( MyStruct.sizeof ); push(MyStruct(1)); } OUTPUT: ctor dtor dtor //C++ CODE #include #include using namespace std; void writeln(string s){ cout << s << '\n'; } struct MyStruct{ int id; MyStruct(int id){ writeln("ctor"); } ~MyStruct(){ writeln("dtor"); } }; MyStruct* obj; template void push(T&& value){ obj[0] = value; } int main() { obj = (MyStruct*)malloc( sizeof(MyStruct) ); push(MyStruct(1)); return 0; } OUTPUT: ctor dtor I didnt expected to see two dtors in D (this destroy any attempt to free resources properly on the destructor). Can someone explain why is this happening and how to achieve the same behavior as c++? Thanks :)
Re: criando modulos em D para classe pessoa[AJUDA]
On Monday, 24 July 2017 at 20:14:23 UTC, SrMordred wrote: On Monday, 24 July 2017 at 19:45:03 UTC, dark777 wrote: pessoal eu tenho umas classes java e estava portando para D e para usar as importaçoes criei os modules nescessarios todos estao dentro da mesma pasta porem ao fazer: $rdmd principal ele retorna o seguinte erro: principal.d(18): Error: octal literals 01023040 are no longer supported, use std.conv.octal!1023040 instead Failed: ["dmd", "-v", "-o-", "principal.d", "-I."] Os codigos sao os que estao abaixo no pastebin https://pastebin.com/CYinHWyQ Erro está aqui: e.setCEP(01023040); um número seguido de zero é considerado um octal (este o erro que está dando) Você provavelmente quer gravar o cep como string: e.setCEP("01023040"); Ou melhor você *deveria* gravar como string.
Re: criando modulos em D para classe pessoa[AJUDA]
On Monday, 24 July 2017 at 19:45:03 UTC, dark777 wrote: pessoal eu tenho umas classes java e estava portando para D e para usar as importaçoes criei os modules nescessarios todos estao dentro da mesma pasta porem ao fazer: $rdmd principal ele retorna o seguinte erro: principal.d(18): Error: octal literals 01023040 are no longer supported, use std.conv.octal!1023040 instead Failed: ["dmd", "-v", "-o-", "principal.d", "-I."] Os codigos sao os que estao abaixo no pastebin https://pastebin.com/CYinHWyQ Erro está aqui: e.setCEP(01023040); um número seguido de zero é considerado um octal (este o erro que está dando) Você provavelmente quer gravar o cep como string: e.setCEP("01023040");
Re: Get complete function declaration
On Tuesday, 18 July 2017 at 13:53:11 UTC, Ivan Kazmenko wrote: On Tuesday, 18 July 2017 at 13:35:49 UTC, SrMordred wrote: There is a way to get the full function(or any other structure) declaration with traits? Or I will have to mount it with std.traits functions? eg. void add(int x, int y){} GetFullFunctionDeclaration!add; //return "void add(int x, int y)" There are several function traits in std.traits (see https://dlang.org/phobos/std_traits.html), which can hopefully be combined to reconstruct a function declaration. I don't see a single method which would do what you want out of the box. Perhaps there is none, since different use cases would require different small subsets of features, and all the orthogonal features are already available. Ivan Kazmenko. Thanks! I´ll have to build one so :)
Get complete function declaration
There is a way to get the full function(or any other structure) declaration with traits? Or I will have to mount it with std.traits functions? eg. void add(int x, int y){} GetFullFunctionDeclaration!add; //return "void add(int x, int y)"
dmd, vibe.d RAM usage when compiling.
I never notice this before, but i tried to put a basic hello world from vibe.d (like the one that are in the dlang front page examples now), into the most basic instance on google cloud (with 600mb of RAM) and the compilation returned "Killed dmd failed with exit code 137." So I look at the RAM usage and saw that when compiling (with dub) it uses 550mb+. So i´m unable to put hello world to work. Aren´t this number a bit too high for a basic example?
Re: Playing with Entity System, performance and D.
On Monday, 19 June 2017 at 19:06:57 UTC, ag0aep6g wrote: For me, alias_fun and op_apply are very close. If anything, alias_fun seems to be slightly faster. Typical output (ldc2 -release -O3): Avoiding bounds checking makes it faster for me (but is unsafe of course): I took a deeper look into dub. "--build=release" make almost all optimizations flags on, except noboundscheck. There is a "--build=release-nobounds" and with it, the numbers got a lot closer (checked on another pc so will not post the numbers now) By the way, if I read it right, indexes is just `0 .. limit`, twice, isn't it? So there's no real point to it in the sample code. When I get rid of indexes and just count up to `limit`, all three versions perform the same. But I guess you're going to have arbitrary values in indexes when you actually use it. Iep :) I choose to keep the indexes 0..limit(and not for eg, random) just to not have cache misses interfering too much with the measurements. Thanks!
Playing with Entity System, performance and D.
I was playing around my ES and different ways of doing it with D. I end up with a performance test of alias func vs ranges vs opApply. code here: https://dpaste.dzfl.pl/a2eff240552f Results on my machine win 10 x64, compiling with: dub run --build=release --arch=x86 --compiler=ldc2 (unable to test with gdc because https://forum.dlang.org/thread/bfmbvxtnqfhhgquay...@forum.dlang.org) Alias func: ~40ms Range Type(front, popFront, emtpy): ~50ms OpApply: ~25ms So first, if I make some really dumb relate to profiling speed or any D code let me know! 1) I thought that ranges were the fastest, but it got the least performant code. 2) opApply was faster than alias func. Its suprising for me. 3) Not possible to return multiple values. So in the front() method I Wrapped a node of pointers.(maybe a performance impact here?, there is a better way of doing it? ) 4) there are no equivalent of declaring Type& x; (ref type) right? 5) I saw sometimes people saying that oApply will be removed. But i find it very powerfull (multiple returns for foreach is a must! eg: foreach(x, y ; myrange) ), and on this case, faster than the others. PS: I know that the performance difference is minimal and may not be noticeable on most(all) use cases, this is just for fun/knowledge with profiling and to understand D behaviors :)