Profiling
I was trying to profile a d program. So I ran: dub build --build=profile. I then ran the program and it produced trace.log and trace.def. I then ran d-profile-viewer and got the following error: std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382): Unexpected '-' when converting from type char[] to type ulong ??:? [0x564a8630fda5] ??:? [0x564a86333286] ??:? [0x564a863199fd] /home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:2382 [0x564a862c89a1] /home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:1941 [0x564a862c86cc] /home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:223 [0x564a862c869c] app.d:1095 [0x564a862cdd71] app.d:1138 [0x564a862ce7ba] ??:? [0x564a863196cb] ??:? [0x564a863195c7] ??:? [0x564a8631941d] /home/jg/dlang/ldc-1.24.0/bin/../import/core/internal/entrypoint.d:42 [0x564a862ce7e4] ??:? __libc_start_main [0x7fd482807cb1] Is d-profile-viewer no longer working? Or did I do something wrong?
Re: Minimize GC memory footprint
On Saturday, 6 February 2021 at 20:24:00 UTC, frame wrote: Hmmm.. with -m64 it's reporting 80 MB used, 203 MB are really marked as private bytes. Constant. If I use GC.minimize() it goes up and down and sometimes consumes more than 203 MB. Best is 100MB. But it doesn't leak endlessly like the 32bit variant. Update: Thanks to Adam's bug report: https://issues.dlang.org/show_bug.cgi?id=21550 My poorly delivered example modified foo() runs also smooth on 32bit now: void foo() { string[] s; foreach (i; 0 .. 50_000_00) { s ~= "a"; } // GC.free(s.ptr); GC.free(GC.addrOf(s.ptr)); } I think the automatic GC is also affected by this issue.
Re: GC.addRange in pure function
On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote: Why using 'new' is allowed in pure functions but calling GC.addRange or GC.removeRange isn't allowed? Does 'new' violate the 'pure' paradigm? Pure functions can only call pure functions and GC.addRange or GC.removeRange is only 'nothrow @nogc'.
Re: Dimensions in compile time
On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote: On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote: On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote: size_t ndim(A)(A arr) { return std.algorithm.count(typeid(A).to!string, '['); } Is there a way to find out the number of dimensions in an array at compile time? yeah. --- template dimensionCount(T) { static if (isArray!T) { static if (isMultiDimensionalArray!T) { alias DT = typeof(T.init[0]); enum dimensionCount = dimensionCount!DT + 1; } else enum dimensionCount = 1; } else enum dimensionCount = 0; } /// unittest { static assert(dimensionCount!char == 0); static assert(dimensionCount!(string[]) == 1); static assert(dimensionCount!(int[]) == 1); static assert(dimensionCount!(int[][]) == 2); static assert(dimensionCount!(int[][][]) == 3); } --- that can be rewritten using some phobos traits too I think, but this piece of code is very old now, more like learner template. dimensionCount!string should be 2. My take without std.traits: template rank(T: U[], U) { enum rank = 1 + rank!U; } template rank(T: U[n], size_t n) { enum rank = 1 + rank!U; } template rank(T) { enum rank = 0; } Here's the version I actually wanted to write: --- enum rank(T) = is(T : U[], U) ? 1 + rank!U : 0; --- But it's not possible, because of 2 language limitations: 1. Ternary operator doesn't allow the different branches to be specialized like `static if` even if the condition is a compile-time constant. 2. `is()` expressions can only introduce an identifier if inside a `static if`. Otherwise, I'd consider this the "idiomatic" / "typical" D solution, since unlike C++, D code rarely (*) overloads and specializes templates. (*) Modern Phobos(-like) code. --- template rank(T) { static if (is(T : U[], U)) enum rank = 1 + rank!U; else enum rank = 0; } unittest { static assert( rank!(char) == 0); static assert( rank!(char[]) == 1); static assert( rank!(string) == 1); static assert( rank!(string[]) == 2); static assert( rank!(string[][]) == 3); static assert( rank!(string[][][]) == 4); } --- Otherwise, the shortest and cleanest solution IMO is this one: --- enum rank(T : U[], U) = is(T : U[], U) ? 1 + rank!U : 0; enum rank(T) = 0; unittest { static assert( rank!(char) == 0); static assert( rank!(char[]) == 1); static assert( rank!(string) == 1); static assert( rank!(string[]) == 2); static assert( rank!(string[][]) == 3); static assert( rank!(string[][][]) == 4); static assert( rank!(char) == 0); static assert( rank!(char[1]) == 1); static assert( rank!(char[1][2]) == 2); static assert( rank!(char[1][2][3]) == 3); static assert( rank!(char[1][2][3][4]) == 4); } --- - Use eponymous template syntax shorthand - Static arrays are implicitly convertible to dynamic arrays, so we can merge the two implementations.
Re: Operator Overloading for Enum
On Monday, 8 February 2021 at 15:56:24 UTC, Michael Brown wrote: Hi all, Is it possible to operator overload on enums? I'd like to do a opCmp() Kind regards, Mike You can create custom struct type with opCmp() and create enum with that type. Example: https://run.dlang.io/is/m7DN66
Operator Overloading for Enum
Hi all, Is it possible to operator overload on enums? I'd like to do a opCmp() Kind regards, Mike
Re: Operator Overloading for Enum
On Monday, 8 February 2021 at 15:56:24 UTC, Michael Brown wrote: Hi all, Is it possible to operator overload on enums? I'd like to do a opCmp() Kind regards, Mike No, it isn't. Only structs and classes can have overloaded operators.
Re: Dimensions in compile time
On Monday, 8 February 2021 at 13:27:14 UTC, Vindex wrote: Thanks everyone! The solution that works for me now looks like this: template ndim(T) { static if (std.traits.isArray!T) { static if (is(typeof(T.init[0]))) { alias SubArrayType = typeof(T.init[0]); enum ndim = ndim!SubArrayType + 1; } else enum ndim = 1; } else enum ndim = 0; } unittest { assert(ndim!(int[]) == 1); assert(ndim!(int[][]) == 2); assert(ndim!(int[4][3]) == 2); assert(ndim!(int[][2][]) == 3); assert(ndim!(string) == 1); } Nice. You should look at Rumbu solution too. It possibly has a better behavior toward the recursive expansion. Also interesting to learn the more advanced use of "is".
Re: Dimensions in compile time
Thanks everyone! The solution that works for me now looks like this: template ndim(T) { static if (std.traits.isArray!T) { static if (is(typeof(T.init[0]))) { alias SubArrayType = typeof(T.init[0]); enum ndim = ndim!SubArrayType + 1; } else enum ndim = 1; } else enum ndim = 0; } unittest { assert(ndim!(int[]) == 1); assert(ndim!(int[][]) == 2); assert(ndim!(int[4][3]) == 2); assert(ndim!(int[][2][]) == 3); assert(ndim!(string) == 1); }
Re: Dimensions in compile time
On Monday, 8 February 2021 at 13:13:33 UTC, Basile B. wrote: On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote: On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote: [...] dimensionCount!string should be 2. My take without std.traits: template rank(T: U[], U) { enum rank = 1 + rank!U; } template rank(T: U[n], size_t n) { enum rank = 1 + rank!U; } template rank(T) { enum rank = 0; } yeah you're right, strings were a special case (I remember now) so that stuff could be stored as literals. well to OP just dont use my dimensionCount template ^^. it should have been declared with the "package" protection in first place; not public.
Re: Dimensions in compile time
On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote: On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote: [...] dimensionCount!string should be 2. My take without std.traits: template rank(T: U[], U) { enum rank = 1 + rank!U; } template rank(T: U[n], size_t n) { enum rank = 1 + rank!U; } template rank(T) { enum rank = 0; } yeah you're right, strings were a special case (I remember now) so that stuff could be stored as literals.
Re: Dimensions in compile time
On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote: On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote: size_t ndim(A)(A arr) { return std.algorithm.count(typeid(A).to!string, '['); } Is there a way to find out the number of dimensions in an array at compile time? yeah. --- template dimensionCount(T) { static if (isArray!T) { static if (isMultiDimensionalArray!T) { alias DT = typeof(T.init[0]); enum dimensionCount = dimensionCount!DT + 1; } else enum dimensionCount = 1; } else enum dimensionCount = 0; } /// unittest { static assert(dimensionCount!char == 0); static assert(dimensionCount!(string[]) == 1); static assert(dimensionCount!(int[]) == 1); static assert(dimensionCount!(int[][]) == 2); static assert(dimensionCount!(int[][][]) == 3); } --- that can be rewritten using some phobos traits too I think, but this piece of code is very old now, more like learner template. dimensionCount!string should be 2. My take without std.traits: template rank(T: U[], U) { enum rank = 1 + rank!U; } template rank(T: U[n], size_t n) { enum rank = 1 + rank!U; } template rank(T) { enum rank = 0; }
Re: Dimensions in compile time
On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote: On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote: [...] yeah. --- template dimensionCount(T) { static if (isArray!T) { static if (isMultiDimensionalArray!T) { alias DT = typeof(T.init[0]); enum dimensionCount = dimensionCount!DT + 1; } else enum dimensionCount = 1; } else enum dimensionCount = 0; } /// unittest { static assert(dimensionCount!char == 0); static assert(dimensionCount!(string[]) == 1); static assert(dimensionCount!(int[]) == 1); static assert(dimensionCount!(int[][]) == 2); static assert(dimensionCount!(int[][][]) == 3); } --- that can be rewritten using some phobos traits too I think, but this piece of code is very old now, more like learner template. well I didn't realize but static array are not handled. I think this is because in first place this was made for a specific usage that was a serializer.
Re: Dimensions in compile time
On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote: size_t ndim(A)(A arr) { return std.algorithm.count(typeid(A).to!string, '['); } Is there a way to find out the number of dimensions in an array at compile time? yeah. --- template dimensionCount(T) { static if (isArray!T) { static if (isMultiDimensionalArray!T) { alias DT = typeof(T.init[0]); enum dimensionCount = dimensionCount!DT + 1; } else enum dimensionCount = 1; } else enum dimensionCount = 0; } /// unittest { static assert(dimensionCount!char == 0); static assert(dimensionCount!(string[]) == 1); static assert(dimensionCount!(int[]) == 1); static assert(dimensionCount!(int[][]) == 2); static assert(dimensionCount!(int[][][]) == 3); } --- that can be rewritten using some phobos traits too I think, but this piece of code is very old now, more like learner template.
Dimensions in compile time
size_t ndim(A)(A arr) { return std.algorithm.count(typeid(A).to!string, '['); } Is there a way to find out the number of dimensions in an array at compile time?