Re: Is old style compile-time foreach redundant?
On 01/06/2018 10:53 PM, Ali Çehreli wrote: On 01/06/2018 06:20 PM, Seb wrote: How about doing sth. similar like for DIP1003? https://dlang.org/spec/contracts.html#pre_post_contracts Already done! :) https://bitbucket.org/acehreli/ddili/commits/2f10c048c2940a49263319d0c23b0ad661449f3e What I meant is, yes, I will do it similar to the body-do change as you suggested. Ali
Re: Is old style compile-time foreach redundant?
On 01/06/2018 06:20 PM, Seb wrote: How about doing sth. similar like for DIP1003? https://dlang.org/spec/contracts.html#pre_post_contracts Already done! :) https://bitbucket.org/acehreli/ddili/commits/2f10c048c2940a49263319d0c23b0ad661449f3e Ali
Re: Is old style compile-time foreach redundant?
On Sunday, 7 January 2018 at 01:52:10 UTC, Ali Çehreli wrote: On 01/06/2018 04:55 PM, Stefan Koch wrote: > When you can use the old style do so. Since it puts less stress on the > compiler in the general case. My question is related to how to update my book. If the difference is mainly about performance, I think I will cover 'static foreach' but also mention old style foreach as a note. Ali How about doing sth. similar like for DIP1003? https://dlang.org/spec/contracts.html#pre_post_contracts Since DIP1003 has been applied the actual function body starts with do. In the past, body was used, and could still be encountered in old code bases.
Re: Is old style compile-time foreach redundant?
On Sunday, 7 January 2018 at 01:08:44 UTC, H. S. Teoh wrote: On Sun, Jan 07, 2018 at 12:55:27AM +, Stefan Koch via Digitalmars-d-learn wrote: On Saturday, 6 January 2018 at 23:25:58 UTC, Ali Çehreli wrote: > Is 'static foreach' sufficient for all needs or is there any > value for regular foreach over compile-time sequences? [...] No it's not. When you can use the old style do so. Since it puts less stress on the compiler in the general case. Really? Based on a recent post by Jonathan Davis, the new static foreach actually runs faster in certain use cases. T That might be true. If you are hitting some constant factor, however the big-o for static foreach is worse then for tuple foreach.
Re: Templates for DRY code
On Saturday, 6 January 2018 at 23:32:42 UTC, Paul Backus wrote: On Saturday, 6 January 2018 at 03:38:35 UTC, codephantom wrote: or even.. a.append( s.to!ConvertToElementType(a) ); That's not valid code of course, but the semantics are all contained in that single chunk. This works: import std.range.primitives: ElementType; a ~= s.to!(ElementType!(typeof(a))); I guess this brings us back to Ali's point about finding the balance between being explicit and fully automatic. I certainly prefer: a.append(s); vs a ~= s.to!(ElementType!(typeof(a))); // this hurts by brain ;-) The only problem with the Ali's suggestion of using append, is we always bring background knowledge everytime we read and write code, and, we all know that you cannot append a string to an array of doubles (that is our background knowledge). I guess if we knew that you can do that now, then 'a.append(s);' would be just fine. But I'm not a big fan of 'implicit' conversions in type safe languages, even when those conversion are type safe. So there's yet another balance to get right.
Re: Is old style compile-time foreach redundant?
On 01/06/2018 04:55 PM, Stefan Koch wrote: > When you can use the old style do so. Since it puts less stress on the > compiler in the general case. My question is related to how to update my book. If the difference is mainly about performance, I think I will cover 'static foreach' but also mention old style foreach as a note. Ali
Re: Is old style compile-time foreach redundant?
On Sun, Jan 07, 2018 at 12:55:27AM +, Stefan Koch via Digitalmars-d-learn wrote: > On Saturday, 6 January 2018 at 23:25:58 UTC, Ali Çehreli wrote: > > Is 'static foreach' sufficient for all needs or is there any value > > for regular foreach over compile-time sequences? [...] > No it's not. > When you can use the old style do so. Since it puts less stress on the > compiler in the general case. Really? Based on a recent post by Jonathan Davis, the new static foreach actually runs faster in certain use cases. T -- No! I'm not in denial!
Re: Is old style compile-time foreach redundant?
On Saturday, 6 January 2018 at 23:25:58 UTC, Ali Çehreli wrote: Is 'static foreach' sufficient for all needs or is there any value for regular foreach over compile-time sequences? Code unrelated to the question: import std.stdio; void main() { // Old style compile-time foreach. This still works // when 'static' is uncommented below. import std.meta : AliasSeq; /* static */ foreach (i; AliasSeq!(1, "hello", 2)) { writeln(i); } // Proper 'static foreach'. import std.range : iota; import std.algorithm : map; static foreach (i; 3.iota.map!(a => a * 10)) { writeln(i); } } Ali No it's not. When you can use the old style do so. Since it puts less stress on the compiler in the general case.
Re: Is old style compile-time foreach redundant?
On Saturday, 6 January 2018 at 23:25:58 UTC, Ali Çehreli wrote: Is 'static foreach' sufficient for all needs or is there any value for regular foreach over compile-time sequences? There is, as far as I've seen, there's nothing old foreach-over-tuple can do that new-style static foreach can't. The big difference is static foreach doesn't introduce a scope, which is great when that's what you want, and only requires an additional set of braces otherwise. In some cases, especially when combined with mixins, this new behavior might manifest bugs at some later point. Simplified example: mixin template declareInts(names...) { static foreach (name; names) { mixin("int "~name~";"); } } As long as you use it with non-duplicate names, this will work great. It will fail the moment a junior programmer decides he wants two ints with the same name. Real-world examples will of course be more involved. Old foreach is however not going away any time soon - there's far too many codebases out there that use the feature. -- Simen
Re: Why is "array operation without destination memory not allowed"?
On Saturday, 6 January 2018 at 23:17:53 UTC, Ali Çehreli wrote: So, apparently a[] * 2 is not an expression in D. The reason must be for performance. If a[]*2 were an expression, the runtime would have to allocate memory and put the results there. Assigning that memory then to b[] would require an additional copy. Current rule puts the burden on the programmer to find the memory. No need to allocate if there's memory already. That makes sense, thanks!
Re: Templates for DRY code
On Saturday, 6 January 2018 at 03:38:35 UTC, codephantom wrote: or even.. a.append( s.to!ConvertToElementType(a) ); That's not valid code of course, but the semantics are all contained in that single chunk. This works: import std.range.primitives: ElementType; a ~= s.to!(ElementType!(typeof(a)));
Is old style compile-time foreach redundant?
Is 'static foreach' sufficient for all needs or is there any value for regular foreach over compile-time sequences? Code unrelated to the question: import std.stdio; void main() { // Old style compile-time foreach. This still works // when 'static' is uncommented below. import std.meta : AliasSeq; /* static */ foreach (i; AliasSeq!(1, "hello", 2)) { writeln(i); } // Proper 'static foreach'. import std.range : iota; import std.algorithm : map; static foreach (i; 3.iota.map!(a => a * 10)) { writeln(i); } } Ali
Re: Why is "array operation without destination memory not allowed"?
On 01/06/2018 03:08 PM, Lily wrote: It seems a bit silly that I have to write int[] a = [1, 2, 300, -29]; int[] b; b.length = 4; b[] = a[] * 2; writeln(b); to do what I would expect int[] a = [1, 2, 300, -29]; writeln(a[] * 2); to do. What am I not understanding? So, apparently a[] * 2 is not an expression in D. It looks like such array-wise operations require a left-hand side with memory for the results. The reason must be for performance. If a[]*2 were an expression, the runtime would have to allocate memory and put the results there. Assigning that memory then to b[] would require an additional copy. Current rule puts the burden on the programmer to find the memory. No need to allocate if there's memory already. However, idiomatic D delays arrays as much as possible. For example, there is no need for destination memory for this example: import std.stdio; import std.algorithm; void main() { int[] a = [1, 2, 300, -29]; writeln(a.map!(x => 2 * x)); } Ali
Re: Why is "array operation without destination memory not allowed"?
On Saturday, 6 January 2018 at 23:08:14 UTC, Lily wrote: What am I not understanding? Where do you expect it to put the result?
Re: TemplateOf behavior
On Saturday, 6 January 2018 at 22:25:48 UTC, ag0aep6g wrote: On Saturday, 6 January 2018 at 19:58:10 UTC, Alex wrote: template T(alias S) { struct T { this(int dummy) { static assert(__traits(isSame, TemplateOf!(T!arr), T)); } } } Now it's a bit more obvious why the assert fails. At the location of the assert, `T` refers to the struct, not the template. To refer to the template, you can prepend a dot, which means that the lookup is done at the module level instead of searching upwards from the local level [1]. Like so: static assert(__traits(isSame, TemplateOf!(.T!arr), .T)); You don't actually need the dot with `T!arr`. The compiler is apparently smart enough to figure out that you mean the template in that case. But it doesn't hurt, either. [1] https://dlang.org/spec/module.html#module_scope_operators Ah... thanks! I chose the other way round, and compare typeof(this) directly now. My false reasoning was, that template parameters are merged to the type before analyzing the types itself.
Why is "array operation without destination memory not allowed"?
It seems a bit silly that I have to write int[] a = [1, 2, 300, -29]; int[] b; b.length = 4; b[] = a[] * 2; writeln(b); to do what I would expect int[] a = [1, 2, 300, -29]; writeln(a[] * 2); to do. What am I not understanding?
Re: How to concatenate a tuple of strings at compile time?
Thanks for the input. Unfortunately I still can't convince the compiler. __traits allMembers includes functions. Trying to filter those with std.traits.isCallable, it complains about strings that can't be read or fields that can't be accessed at compile time. Affected are both solutions. So any insight in why mixin(fullyQualifiedName!T ~ "." ~ item) produces a compiler error saying that string can't be accessed at compile time would be very appreciated. Same goes for [tuple(..)].filter!(item => !isCallable!(mixin(fullyQualifiedName!T ~ "." ~ item))).join;
Re: TemplateOf behavior
On Saturday, 6 January 2018 at 19:58:10 UTC, Alex wrote: Given the code above, why the static assert inside the mixing template constructor yields false, while the others yield true? Let's resolve the mixin and write out the `T` template in the verbose form. It looks like this then: template T(alias S) { struct T { this(int dummy) { static assert(__traits(isSame, TemplateOf!(T!arr), T)); } } } Now it's a bit more obvious why the assert fails. At the location of the assert, `T` refers to the struct, not the template. To refer to the template, you can prepend a dot, which means that the lookup is done at the module level instead of searching upwards from the local level [1]. Like so: static assert(__traits(isSame, TemplateOf!(.T!arr), .T)); You don't actually need the dot with `T!arr`. The compiler is apparently smart enough to figure out that you mean the template in that case. But it doesn't hurt, either. [1] https://dlang.org/spec/module.html#module_scope_operators
Re: How to concatenate a tuple of strings at compile time?
On Saturday, 6 January 2018 at 21:41:56 UTC, user1205 wrote: On Saturday, 6 January 2018 at 21:38:41 UTC, user1205 wrote: On Saturday, 6 January 2018 at 21:35:19 UTC, user1205 wrote: On Saturday, 6 January 2018 at 19:35:33 UTC, paul wrote: Hi! How to concatenate a tuple of strings at compile time? [...] ``` template staticCat(T...) if (T.length) { import std.array; enum staticCat = [T].join(); } enum elems1 = tuple("foo", "bar"); enum elems2 = tuple("0", "1", "2"); enum elems3 = tuple("a"); pragma(msg, staticCat!(elems1.expand)); pragma(msg, staticCat!(elems2.expand)); pragma(msg, staticCat!(elems3.expand)); ``` +1 Yeah i upvote myself. Best solution so far. Maybe tweak the constraint. BTW rule of thumb: when you have the choice between template metaprogramming and CTFE use CTFE, it's faster. The solution based on std.array.join is CTFE.
Re: How to concatenate a tuple of strings at compile time?
On Saturday, 6 January 2018 at 21:38:41 UTC, user1205 wrote: On Saturday, 6 January 2018 at 21:35:19 UTC, user1205 wrote: On Saturday, 6 January 2018 at 19:35:33 UTC, paul wrote: Hi! How to concatenate a tuple of strings at compile time? [...] Hello, this simple template does the job: ``` template staticCat(T...) if (T.length) { static if (T.length == 1) enum staticCat = T[0]; else static if (T.length == 2) alias staticCat = staticCat!(T[0] ~ T[1]); else static if (T.length > 2) alias staticCat = staticCat!(T[0] ~ T[1], T[2..$]); } enum elems1 = tuple("foo", "bar"); enum elems2 = tuple("0", "1", "2"); enum elems3 = tuple("a"); ``` pragma(msg, staticCat!(elems1.expand)); pragma(msg, staticCat!(elems2.expand)); pragma(msg, staticCat!(elems3.expand)); There might be other solutions, maybe even in std.meta. There is also this one, less verbose, more efficient (not recursive template instances): ``` template staticCat(T...) if (T.length) { import std.array; enum staticCat = [T].join(); } enum elems1 = tuple("foo", "bar"); enum elems2 = tuple("0", "1", "2"); enum elems3 = tuple("a"); pragma(msg, staticCat!(elems1.expand)); pragma(msg, staticCat!(elems2.expand)); pragma(msg, staticCat!(elems3.expand)); ``` +1 Yeah i upvote myself. Best solution so far. Maybe tweak the constraint.
Re: How to concatenate a tuple of strings at compile time?
On Saturday, 6 January 2018 at 19:35:33 UTC, paul wrote: Hi! How to concatenate a tuple of strings at compile time? [...] Hello, this simple template does the job: ``` template staticCat(T...) if (T.length) { static if (T.length == 1) enum staticCat = T[0]; else static if (T.length == 2) alias staticCat = staticCat!(T[0] ~ T[1]); else static if (T.length > 2) alias staticCat = staticCat!(T[0] ~ T[1], T[2..$]); } enum elems1 = tuple("foo", "bar"); enum elems2 = tuple("0", "1", "2"); enum elems3 = tuple("a"); ``` pragma(msg, staticCat!(elems1.expand)); pragma(msg, staticCat!(elems2.expand)); pragma(msg, staticCat!(elems3.expand)); There might be other solutions, maybe even in std.meta.
Re: How to concatenate a tuple of strings at compile time?
On Saturday, 6 January 2018 at 21:35:19 UTC, user1205 wrote: On Saturday, 6 January 2018 at 19:35:33 UTC, paul wrote: Hi! How to concatenate a tuple of strings at compile time? [...] Hello, this simple template does the job: ``` template staticCat(T...) if (T.length) { static if (T.length == 1) enum staticCat = T[0]; else static if (T.length == 2) alias staticCat = staticCat!(T[0] ~ T[1]); else static if (T.length > 2) alias staticCat = staticCat!(T[0] ~ T[1], T[2..$]); } enum elems1 = tuple("foo", "bar"); enum elems2 = tuple("0", "1", "2"); enum elems3 = tuple("a"); ``` pragma(msg, staticCat!(elems1.expand)); pragma(msg, staticCat!(elems2.expand)); pragma(msg, staticCat!(elems3.expand)); There might be other solutions, maybe even in std.meta. There is also this one, less verbose, more efficient (not recursive template instances): ``` template staticCat(T...) if (T.length) { import std.array; enum staticCat = [T].join(); } enum elems1 = tuple("foo", "bar"); enum elems2 = tuple("0", "1", "2"); enum elems3 = tuple("a"); pragma(msg, staticCat!(elems1.expand)); pragma(msg, staticCat!(elems2.expand)); pragma(msg, staticCat!(elems3.expand)); ```
Re: How to concatenate a tuple of strings at compile time?
On Saturday, 6 January 2018 at 19:35:33 UTC, paul wrote: Hi! How to concatenate a tuple of strings at compile time? Something like that maybe ? import std.stdio; import std.meta; enum connected = () { auto something = AliasSeq!("one", "two", "three"); string res = ""; static foreach(item; something) {{ res ~= item; }} return res; }(); void main() { writefln("connected = %s", connected); }
TemplateOf behavior
//code starts import std.traits; void main() { static assert(__traits(isSame, TemplateOf!(T!arr), T)); } size_t[] arr; struct T(alias S) { mixin Contents!() contents; this(Args)(ref Args args) { contents.__ctor(42); } } static assert(__traits(isSame, TemplateOf!(T!arr), T)); mixin template Contents() { int dummy; this(int dummy) { //static assert(__traits(isSame, TemplateOf!(T!arr), T)); } } //code ends Given the code above, why the static assert inside the mixing template constructor yields false, while the others yield true?
How to concatenate a tuple of strings at compile time?
Hi! How to concatenate a tuple of strings at compile time? Appending to an enum or an immutable string in a static foreach doesn't work. (And shadowing the thing doesn't work either) a) Calling a function recursively doesn't work because I had to turn the tuple into an array which cannot be read at compile time. b) a) enum/immutable string connected; static foreach(item; __traits(something)) connected ~= item; b) string concat(string[] a, string b = "", index i = 0) { if (s.length - 1 == index) { return b ~ a[$-1]; } else { return concat(a,b[index],index+1); } } concat([__traits(something)]); An internet search didn't reward any solution but probably I'm just missing something very trivial. Any clues would be very appreciated. Thanks. On a different note, what I want to achieve is to automatically generate a function call that hides the fact of a struct being initialized. something like this: struct X { int a; string b; } class C { X _x; this(int a, string b) { _x = X(a, b); } }
Re: Help optimizing UnCompress for gzipped files
On 05.01.18 23:04, Steven Schveighoffer wrote: > On 1/5/18 3:09 PM, Christian Köstlin wrote: >> On 05.01.18 15:39, Steven Schveighoffer wrote: >>> Yeah, I guess most of the bottlenecks are inside libz, or the memory >>> allocator. There isn't much optimization to be done in the main program >>> itself. >>> >>> D compiles just the same as C. So theoretically you should be able to >>> get the same performance with a ported version of your C code. It's >>> worth a shot. >> I added another version that tries to do the "same" as the c version >> using mallocator, but i am still way off, perhaps its creating too many >> ranges on the underlying array. but its around the same speed as your >> great iopipe thing. > > Hm... I think really there is some magic initial state of the allocator, > and that's what allows it to go so fast. > > One thing about the D version, because druntime is also using malloc > (the GC is backed by malloc'd data after all), the initial state of the > heap is quite different from when you start in C. It may be impossible > or nearly impossible to duplicate the performance. But the flipside (if > this is indeed the case) is that you won't see the same performance in a > real-world app anyway, even in C. > > One thing to try, you preallocate the ENTIRE buffer. This only works if > you know how many bytes it will decompress to (not always possible), but > it will take the allocator out of the equation completely. And it's > probably going to be the most efficient method (you aren't leaving > behind smaller unused blocks when you realloc). If for some reason we > can't beat/tie the C version doing that, then something else is going on. yes ... this is something i forgot to try out ... will do now :) mhh .. interesting numbers ... c is even faster, my d lowlevel solution is also a little bit faster, but much slower than the no copy version (funnily, no copy is the wrong name, it just overwrites all the data in a small buffer). >> My solution does have the same memory leak, as I am not sure how to best >> get the memory out of the FastAppender so that it is automagically >> cleaned up. Perhaps if we get rc things, this gets easier? > > I've been giving some thought to this. I think iopipe needs some buffer > management primitives that allow you to finagle the buffer. I've been > needing this for some time anyway (for file seeking). Right now, the > buffer itself is buried in the chain, so it's hard to get at the actual > buffer. > > Alternatively, I probably also need to give some thought to a mechanism > that auto-frees the memory when it can tell nobody is still using the > iopipe. Given that iopipe's signature feature is direct buffer access, > this would mean anything that uses such a feature would have to be unsafe. yes .. thats tricky ... one question about iopipe. is it possible to transform the elements in the pipe as well ... e.g. away from a buffer of bytes to json objects? -- Christian Köstlin
Re: Error: variable i cannot be read at compile time
On Saturday, 6 January 2018 at 06:47:33 UTC, Vino wrote: On Friday, 5 January 2018 at 18:00:34 UTC, thedeemon wrote: On Friday, 5 January 2018 at 17:59:32 UTC, thedeemon wrote: Tuple!( staticMap!(Arr, ColumnTypes) ) res; // array of tuples Sorry, I meant tuple of arrays, of course. Hi Deemon, Thank you very much, I tested your code, initially the code did not produce the expected output, and found an issue in the the key line of code as below, after updating the output was as expected. Can you please let me know how to change the array from standard array to container array. Here's a version with Array, it's very similar: import std.algorithm: countUntil, joiner, sort, uniq, map; import std.csv: csvReader; import std.stdio: File, writeln; import std.typecons: Tuple, tuple; import std.meta; import std.file : readText; import std.container.array; alias ColumnTypes = AliasSeq!(string, string, int); auto readData(string fname) { // returns tuple of Arrays Tuple!( staticMap!(Array, ColumnTypes) ) res; foreach (record; fname.readText.csvReader!(Tuple!ColumnTypes)('\t')) foreach(i, T; ColumnTypes) res[i].insert(record[i]); return res; } auto compress(T)(ref Array!T col) { auto vals = Array!T( sort(col.dup[]).uniq ); auto ks = Array!ptrdiff_t( col[].map!(v => vals[].countUntil(v)) ); return tuple(vals, ks); } void main() { auto columns = readData("data.csv"); foreach(i, ColT; ColumnTypes) { auto vk = compress(columns[i]); writeln(vk[0][]); //output data, you can write files here writeln(vk[1][]); //output indices } }
Re: C++ Interop
On Saturday, 6 January 2018 at 13:51:54 UTC, qznc wrote: It would be great to have std::vector and std::string out of the box in D, but putting it into druntime? Druntime is supposed to be shared among all frontends, isn't it? GCC and Clang probably do not have equivalent vector/string classes that the same D code can be used. +1 Supporting std::vector and std::string would be a major help
Passing Template to Function
Hi All, Request you help on the below program as it error out with the below error Error: UDictCompression.d(31): Error: template UDictCompression.compress cannot deduce function from argument types !()(string), candidates are: UDictCompression.d(19): UDictCompression.compress(T)(Array!T col) Program: import std.algorithm: countUntil, joiner, sort, uniq, map; import std.csv: csvReader; import std.stdio: File, writeln; import std.typecons: Tuple, tuple; import std.meta: AliasSeq; import std.container.array; alias ColumnTypes = AliasSeq!(string, string, int); alias Arr(T) = Array!T; auto readData() { auto file = File("C:\\Users\\bheev1\\Desktop\\Current\\Script\\Others\\TColRead.csv", "r"); Arr!(Tuple!ColumnTypes) res; foreach (record; file.byLineCopy.joiner("\n").csvReader!(Tuple!ColumnTypes)) { res.insertBack(record); } return res; } auto compress(T)(Array!T col) { Arr!int ks; Array!T vals; vals.insertBack(sort(col.dup[]).uniq); ks.insertBack(col.map!(v => vals.countUntil(v))); return tuple(vals, ks); } void main() { auto columns = readData[]; foreach(r; columns) { foreach(i, ColT; ColumnTypes) { auto vk = compress(r[i]); writeln(vk[0][], vk[1][]); } } } From, Vino.B
Re: Error: non-shared method Node.~this is not callable using a shared object
On Saturday, 6 January 2018 at 11:23:13 UTC, ChangLong wrote: This code is not working. --- shared struct Stack { Node n = void ; } struct Node { ~this() {} } --- Error: non-shared method test.Node.~this is not callable using a shared object Is this a bug ? Node.~this is not called from Stack. take a look at http://ddili.org/ders/d.en/struct.html constructor and destructor for struct must be static.
Re: Does dub support generating source files?
On Saturday, 6 January 2018 at 13:40:54 UTC, rikki cattermole wrote: On 06/01/2018 1:23 PM, Bastiaan Veelo wrote: I could script a custom preBuildCommand that checks modification dates and supplies the Pegged include path explicitly but that seems hackish and non-portable and typically something that the build system should do. See: https://github.com/Abscissa/gen-package-version If I read this correctly, it basically takes the script route (rdmd) somewhat like the above [1], but taking care to stay portable by inquiring dub. I should be able to make this work, but I wish dub supported adding simple make rules... [1] https://github.com/Abscissa/gen-package-version/blob/515138077fb78af5c4154f13990cee23e54ed9e7/src/genPackageVersion/genDModule.d#L60
Re: C++ Interop
On Saturday, 6 January 2018 at 11:20:01 UTC, Seb wrote: On Saturday, 6 January 2018 at 11:17:56 UTC, Seb wrote: On Friday, 5 January 2018 at 13:02:12 UTC, qznc wrote: I'm exploring [0] C++ interop after watching Walter's presentation [1]. [...] I know about this: https://github.com/Remedy-Entertainment/binderoo https://github.com/dlang/druntime/pull/1802 And: https://github.com/dlang/druntime/pull/1316 Also I think Ian (@ibuclaw) and @Razvan7 are currently working on a header generation tool from D sources to C++ headers. It would be great to have std::vector and std::string out of the box in D, but putting it into druntime? Druntime is supposed to be shared among all frontends, isn't it? GCC and Clang probably do not have equivalent vector/string classes that the same D code can be used.
Re: Does dub support generating source files?
On Saturday, 6 January 2018 at 13:40:54 UTC, rikki cattermole wrote: On 06/01/2018 1:23 PM, Bastiaan Veelo wrote: Can dub do this or is this a thing for reggae? It must work on Windows though. Thanks! See: https://github.com/Abscissa/gen-package-version That seems to be a good tip, thanks. I'll need to study what's going on there.
Re: -L--demangle=dlang doesn't work
On Saturday, 6 January 2018 at 05:44:28 UTC, Venkat wrote: Why does gcc say "unknown demangling style `dlang'" ? Do I need GDC for demangling to work ? Check your version of binutils with `ld --version`. It looks like it was added in v2.25: http://forum.dlang.org/post/rvoqllpimfskvlabp...@forum.dlang.org I tested with 2.29.1 and it worked fine for me. Mike
Re: Does dub support generating source files?
On 06/01/2018 1:23 PM, Bastiaan Veelo wrote: Hi, One of my source files (epparser.d) should be generated by calling rdmd on another soure file (make.d) and therefore should depend on changes in make.d and an additional module (epgrammar.d). An include path to Pegged is required for compilation. epparser.d should be part of the main project, but make.d and epgrammar.d should not. I have tried using a dub subpackage for this with preBuildCommands ("cd ./subpackage && dub run") in the main project, but that doesn't update epparser.d when epgrammar.d changes (oddly enough; is does update when subpackage targetType is "library", but it must be "executable"). epparser.d should not be generated unnecessarily. I could script a custom preBuildCommand that checks modification dates and supplies the Pegged include path explicitly but that seems hackish and non-portable and typically something that the build system should do. Can dub do this or is this a thing for reggae? It must work on Windows though. Thanks! See: https://github.com/Abscissa/gen-package-version
Does dub support generating source files?
Hi, One of my source files (epparser.d) should be generated by calling rdmd on another soure file (make.d) and therefore should depend on changes in make.d and an additional module (epgrammar.d). An include path to Pegged is required for compilation. epparser.d should be part of the main project, but make.d and epgrammar.d should not. I have tried using a dub subpackage for this with preBuildCommands ("cd ./subpackage && dub run") in the main project, but that doesn't update epparser.d when epgrammar.d changes (oddly enough; is does update when subpackage targetType is "library", but it must be "executable"). epparser.d should not be generated unnecessarily. I could script a custom preBuildCommand that checks modification dates and supplies the Pegged include path explicitly but that seems hackish and non-portable and typically something that the build system should do. Can dub do this or is this a thing for reggae? It must work on Windows though. Thanks!
Re: C++ Interop
On Friday, 5 January 2018 at 13:02:12 UTC, qznc wrote: I'm exploring [0] C++ interop after watching Walter's presentation [1]. I hit a block with classes as template parameters. This means vector works, but vector does not. D seems to map vector!Foo to vector. Likewise shared_ptr is a problem. Any way to fix that on the D side? The ugly workaround is to adapt the C++ code. I understand that this mapping makes sense for function calls because bar(Foo f) in D maps to bar(Foo *f) in C++. And C++ bar(Foo f) has no equivalent in D because classes are reference types. On a related note, C++ interop requires to redeclare or even reimplement C++ code. Has anybody started a libcpp-in-d project? I'm looking for basics like vector and string. [0] https://github.com/qznc/d-cpptest [1] https://youtu.be/IkwaV6k6BmM is C++ support in LDC better than what we have with DMD? i did checkout your code btw and could not enjoy it more. :)
Error: non-shared method Node.~this is not callable using a shared object
This code is not working. --- shared struct Stack { Node n = void ; } struct Node { ~this() {} } --- Error: non-shared method test.Node.~this is not callable using a shared object Is this a bug ? Node.~this is not called from Stack.
Re: C++ Interop
On Saturday, 6 January 2018 at 11:17:56 UTC, Seb wrote: On Friday, 5 January 2018 at 13:02:12 UTC, qznc wrote: I'm exploring [0] C++ interop after watching Walter's presentation [1]. [...] I know about this: https://github.com/Remedy-Entertainment/binderoo https://github.com/dlang/druntime/pull/1802 And: https://github.com/dlang/druntime/pull/1316 Also I think Ian (@ibuclaw) and @Razvan7 are currently working on a header generation tool from D sources to C++ headers.
Re: C++ Interop
On Friday, 5 January 2018 at 13:02:12 UTC, qznc wrote: I'm exploring [0] C++ interop after watching Walter's presentation [1]. [...] I know about this: https://github.com/Remedy-Entertainment/binderoo https://github.com/dlang/druntime/pull/1802
Re: Templates for DRY code
On Saturday, 6 January 2018 at 03:08:19 UTC, Ali Çehreli wrote: I agree with your point as well. A better name can help there a little. void ConvertAndAppend(T, S)(ref T[] arr, S s) { arr ~= s.to!T; } problem solved ;-) btw. I never thought that I would be able (or actually..willing) to program using templates, still I found D. Thanks to those responsible for making them so easy to use (presumably Walter and Andrei).
Re: Error: variable i cannot be read at compile time
On Saturday, 6 January 2018 at 06:47:33 UTC, Vino wrote: On Friday, 5 January 2018 at 18:00:34 UTC, thedeemon wrote: On Friday, 5 January 2018 at 17:59:32 UTC, thedeemon wrote: Tuple!( staticMap!(Arr, ColumnTypes) ) res; // array of tuples Sorry, I meant tuple of arrays, of course. Hi Deemon, Thank you very much, I tested your code, initially the code did not produce the expected output, and found an issue in the the key line of code as below, after updating the output was as expected. Can you please let me know how to change the array from standard array to container array. auto ks = col.map!(v => col.countUntil(v)).array; // Your code(col.countUntil) auto ks = col.map!(v => vals.countUntil(v)).array; // Changed code(vals.countUntil) From, Vino.B Hi Deemon, Was able to convert 50% of the code to container array and facing some issue import std.algorithm: countUntil, joiner, sort, uniq, map; import std.csv: csvReader; import std.stdio: File, writeln; import std.typecons: Tuple, tuple; import std.meta: AliasSeq; import std.container.array; alias ColumnTypes = AliasSeq!(string, string, int); alias Arr(T) = Array!T; auto readData() { auto file = File("C:\\Users\\bheev1\\Desktop\\Current\\Script\\Others\\TColRead.csv", "r"); Arr!(Tuple!ColumnTypes) res; foreach (record; file.byLineCopy.joiner("\n").csvReader!(Tuple!ColumnTypes)) { res.insertBack(record); } return tuple(res[]); // replace this line with writeln(res[]); gives the expected output } auto compress(T)(Array!T col) { Arr!int ks; Array!T vals; vals.insertBack(sort(col.dup[]).uniq); ks.insertBack(col.map!(v => vals.countUntil(v))); return tuple(vals, ks); } void main() { auto columns = readData(); foreach(i, ColT; ColumnTypes) { //Facing some issue at this point auto vk = compress(columns[i]); writeln(vk[0][], vk[1][]); } } From, Vino.B