Re: appender!(dchar[]) put fail
On 6/13/15 6:45 AM, kerdemdemir wrote: I have two strings(stringB,stringC) which I need to repeat(bCount times, cCountTimes) and then chain. auto charAppender = appender!(dchar[]); auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); This compiles and works ok, But when I try to append new string to charAppender : charAppender.put(totalStr); Error: template std.array.join cannot deduce function from argument types I tried: charAppender.put(totalStr.array()); charAppender.data.chain(totalStr); charAppender.data.chain(totalStr.array()); etc... I always get compile errors. Do you have any idea or fix about that? Have you tried: put(charAppender, totalStr); It is not recommended to use charAppender.put directly, unless you know it will work. This is a frequent cause of problems (using .put on an output range directly). -Steve
Re: What is D's minimum requirements on Mac?
On 14/06/2015 12:32 p.m., Adam D. Ruppe wrote: On Friday, 12 June 2015 at 07:17:44 UTC, Jacob Carlborg wrote: I'm running a OS X 10.7 on Macbook from 2006, it's working perfectly fine. Although the whole computer it's quite slow, it only has 2 GB of RAM. Thanks everyone. A coworker says he is selling an old Mac of his from 2010 and it sounds like I can make D work, so I think I'm going to snatch that up and see about starting to officially support macs in my libs (beyond just it is close enough to posix with x11 which is what I'm doing now) OSX doesn't support X11 now. It's called XQuartz and must be manually installed. Oh and e.g. Derelict-GL/Derelict-Util doesn't play nicely in this act. Been there done that. Resulted to using Objective-C code. But atleast you can commit that static library to repo. Since you only need to support x86_64 OSX Cocoa.
how come is this legal? 'void fun(int){ }' ?
I understand this is legal for declaration wo definition (void fun(int);) but why allow this: void test(int){} ?
Re: how come is this legal? 'void fun(int){ }' ?
On Sun, 14 Jun 2015 05:11:17 +, Maxim Fomin wrote: On Sunday, 14 June 2015 at 01:20:39 UTC, Timothee Cour wrote: I understand this is legal for declaration wo definition (void fun(int);) but why allow this: void test(int){} ? Actually it is void test(int _param_0) { } You can test by compiling void test(int) { _param_0 = 0; } Nameless parameters are simulated by providing internal symbol as above. yet one shouldn't rely on generated names, they are undocumented on purpose, and can change without a notice and deprecation cycle. signature.asc Description: PGP signature
Are stack+heap classes possible in D?
I have read that in D structs are always allocated on the stack while classes are always allocated on the heap. Well, I often have classes where I want some instances on the stack, some on the heap. So.. what to do?
Re: Are stack+heap classes possible in D?
On Sunday, 14 June 2015 at 01:31:25 UTC, Adam D. Ruppe wrote: On Sunday, 14 June 2015 at 00:52:20 UTC, FujiBar wrote: I have read that in D structs are always allocated on the stack while classes are always allocated on the heap. That's not true; it is a really common misconception. Putting a struct on the heap is trivial and built into the language: `S* s = new S();` Putting a class on the stack is a bit trickier, but the standard library provides a helper to do it: http://dlang.org/phobos/std_typecons.html#scoped follow the examples given there. Thanks!
Re: appender!(dchar[]) put fail
On 06/13/2015 04:23 AM, Quentin Ladeveze wrote: The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work. To answer Erdem's later question, loops with side effects can be replaced with std.algorithm.each: totalStr.each!(elem = charAppender.put(elem)); One issue with that method that I am frequently reminded of is that although the lambda's = syntax is by definition a return statement, 'each' does not do anything with the returned value. (Regardless of whether the lambda returns anything or not.) Ali
Re: how come is this legal? 'void fun(int){ }' ?
On Sunday, 14 June 2015 at 01:20:39 UTC, Timothee Cour wrote: I understand this is legal for declaration wo definition (void fun(int);) but why allow this: void test(int){} ? Actually it is void test(int _param_0) { } You can test by compiling void test(int) { _param_0 = 0; } Nameless parameters are simulated by providing internal symbol as above.
Re: how come is this legal? 'void fun(int){ }' ?
Sometimes you have empty functions and/or unused parameters just to fulfill some interface but you don't actually care about the arguments passed. No need to name them if you aren't going to use them.
Re: Are stack+heap classes possible in D?
On Sunday, 14 June 2015 at 00:52:20 UTC, FujiBar wrote: I have read that in D structs are always allocated on the stack while classes are always allocated on the heap. That's not true; it is a really common misconception. Putting a struct on the heap is trivial and built into the language: `S* s = new S();` Putting a class on the stack is a bit trickier, but the standard library provides a helper to do it: http://dlang.org/phobos/std_typecons.html#scoped follow the examples given there.
Re: __traits getMember is context sensetive?
I have another one :) module test; struct S{ string member1; int member2; } string test(string[] a) { const S s = { member1:It is also important to go to Mars!}; const string y = a[0]; return y; } void main() { enum e = [member1,member2]; pragma(msg, e[0]); pragma(msg, test(e)); } Compiles, works fine while module test; struct S{ string member1; int member2; } string test(string[] a) { const S s = { member1:It is also important to go to Mars!}; const string y = a[0]; return __traits(getMember, s, y); } void main() { enum e = [member1,member2]; pragma(msg, e[0]); pragma(msg, test(e)); } spits out following: test.d(11): Error: variable a cannot be read at compile time test.d(12):while evaluating y.init test.d(12): Error: string expected as second argument of __traits getMember instead of __error test.d(12): Error: cannot implicitly convert expression (false) of type bool to string member1 test.d(19): Error: CTFE failed because of previous errors in test test.d(19):while evaluating pragma(msg, test([member1, member2])) If i use member1 directly it works. What am I missing here? Thanks for your help
Re: __traits getMember is context sensetive?
oh, seems that i managed to make everything even less understandable... signature.asc Description: PGP signature
Re: __traits getMember is context sensetive?
On Sat, 13 Jun 2015 23:55:53 +, JDemler wrote: After a bit of rethinking: I guess the compiler goes through 2 loops: the first resolves __traits, the second does ctfe. That would explain this behavior. a is not present to the compiler while it tries to resolve my __traits call, but will be present in case of ctfe. the thing is that `a` (and `s` for that matter) is a *runtime* variable. even if you can see that it will not change and effectively a constant, compiler doesn't see that and doesn't assume that it can use such constants in CTFE. the difference is like this: enum s0 = string0; // compile time constant string s1 = string1; // runtime constant compiler doesn't do data flow analysis to prove that s1 will never change and it can be used as compile time constant, it simply plays a crybaby here, complaining that it can't read runtime variable value in compile time. here's what you can do instead: immutable S s = { member1:It is also important to go to Mars!}; template test(string[] a) { enum y = a[0]; enum test = __traits(getMember, s, y); } void main () { enum e = [member1,member2]; pragma(msg, e[0]); pragma(msg, test!(e)); } signature.asc Description: PGP signature
Re: appender!(dchar[]) put fail
On Saturday, 13 June 2015 at 13:09:20 UTC, Dennis Ritchie wrote: auto stringB = readln.chomp.map!(to!dchar).array; auto stringC = readln.chomp.map!(to!dchar).array; auto charAppender = appender!(dchar[][]); auto totalStr = stringB.repeat(3).chain(stringC.repeat(5)); charAppender.put(totalStr); writeln(charAppender); charAppender.put(cd.dup); charAppender.put(testd.dup); writeln(charAppender); Thanks lot that is really good. One more question I am asking those kind of questions to understand and not ask same stuff over and over, : auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour?
Re: appender!(dchar[]) put fail
On Saturday, 13 June 2015 at 13:32:19 UTC, kerdemdemir wrote: One more question I am asking those kind of questions to understand and not ask same stuff over and over, : auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour? std.range.repeat is a lazy version unlike std.array.replicate: 5.repeat(3).writeln; // a lazy version // [5, 5, 5] [5].replicate(3).writeln; // [5, 5, 5] // but [5].repeat(3).writeln; // a lazy version // [[5], [5], [5]]
Re: appender!(dchar[]) put fail
On Saturday, 13 June 2015 at 12:02:10 UTC, kerdemdemir wrote: The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work. But I can see in the example of array.appander(http://dlang.org/phobos/std_array.html#appender) int[] a = [ 1, 2 ]; auto app2 = appender(a); app2.put(3); app2.put([ 4, 5, 6 ]); --- appender accepts another array. Why this is not same with dchar ? It is the same, but totalStr is not a dchar[]. It's a Result (a type internal to the chain function ) which is a range. The foreach loop iterates over Result, which returns dchar[]. So if you try to do something like that : charAppender.put(totalStr.array), it won't work because totalStr.array is a dchar[][].
Re: appender!(dchar[]) put fail
On Saturday, 13 June 2015 at 13:01:29 UTC, kerdemdemir wrote: Sorry to making the discussion longer and wasting your times. But I am looking for a way without for loops. Also looping every element one by one does not seems very efficient to me. Any advices for that? Maybe it fit? auto stringB = readln.chomp.map!(to!dchar).array; auto stringC = readln.chomp.map!(to!dchar).array; auto charAppender = appender!(dchar[][]); auto totalStr = stringB.repeat(3).chain(stringC.repeat(5)); charAppender.put(totalStr); writeln(charAppender); charAppender.put(cd.dup); charAppender.put(testd.dup); writeln(charAppender);
Re: appender!(dchar[]) put fail
It is the same, but totalStr is not a dchar[]. It's a Result (a type internal to the chain function ) which is a range. The foreach loop iterates over Result, which returns dchar[]. So if you try to do something like that : charAppender.put(totalStr.array), it won't work because totalStr.array is a dchar[][]. Sorry to making the discussion longer and wasting your times. But I am looking for a way without for loops. Also looping every element one by one does not seems very efficient to me. Any advices for that?
Re: appender!(dchar[]) put fail
On Saturday, 13 June 2015 at 13:32:19 UTC, kerdemdemir wrote: Thanks lot that is really good. One more question I am asking those kind of questions to understand and not ask same stuff over and over, : Don't worry, there is learn in D.learn auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour? Two functions doing the same thing would be the illogical thing, no ?
Re: Conditional Compilation Multiple Versions
On Saturday, 13 June 2015 at 00:47:37 UTC, Mike Parker wrote: // config.d version(One) enum One = true; else enum One = false; version(Two) enum Two = true; else enum Two = false; // other.d import config; static if(One || Two) { ... } Taking it one step further: template Version(string name) { mixin( version(~name~) enum Version = true; else enum Version = false; ); } static if(Version!One || Version!Two) { ... }
Re: Qualified destructors / immutable objects
On Friday, 12 June 2015 at 15:36:22 UTC, anonymous wrote: no need for ~this() to modify immutable data: class C { int a; this(int a) { this.a = a; } } struct S { C elem = new C(42); } void main() { import std.stdio; immutable(S) s1; // Error: cannot modify immutable expression s1.elem.a // s1.elem.a = 43; writeln(s1.elem.a); S s2; s2.elem.a = 123; writeln(s1.elem.a); } Prints: 42 123 Is there an existing issue on issue.dlang.org? If not can you report it
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 15:21:19 UTC, Dennis Ritchie wrote: Hello, everyone! I like to work with arrays of strings like `string[] strArray`, but unfortunately, they are immutable. I do not like to work with arrays of strings such as `char[][] strArray`, because it is necessary to apply the method .dup each substring to make them work :) Huh? You mean with string literals? That would be a rather silly reason to avoid `char[]`. Please show an example of .dup you'd like to avoid. I understand that the type of `string[]` to D is a simple data type than `char[][]`, Are you saying that `string[]` is simpler than `char[][]`? That's not true: `string` is an alias for `immutable(char)[]`, so `string[]` is the same as `immutable(char)[][]`. but it seems to me that the problem is solved in C++: std::vectorstd::string stdArray; I wish to propose the creation of new types of data D: str, wstr, dstr, which will be the analogs of C++ `std::vectorstd::string`. Before jumping to a solution, please elaborate on the perceived problem. I have a feeling that there is none.
Serialization array of structure
Look like I am doing serialization wrong way: struct DBFields { Date date; string tag; int popularity; } DBFields [] dbfields; DBFields dbfield; . dbfields ~= dbfield; writeln(serializeToJson(dbfields)); As result I am getting only first string. [{popularity:1,tag:webserver,date:2008-08-21}] But dbfields should include not only one string, but much more. What I am doing wrong?
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 15:45:34 UTC, anonymous wrote: Please show an example of .dup you'd like to avoid. For example, if you need to create a five-dimensional array of strings :)
Re: Serialization array of structure
Oh, sorry, the error was in another place.
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 16:20:46 UTC, anonymous wrote: Do you like to write? char[][] strArray = [foo.dup, bar.dup, baz.dup]; Ok. That's all you're on about? Basically you'd like this: char[] s = foo; and this: char[][] a = [[foo]]; etc. Yes. That's right, and not otherwise :) Yeah, that would be neat. But typing out .dup isn't that bad, and converting a `string[]` to a `char[][]` is simple: import std.conv: to; auto a = [foo].to!(char[][]); Yes, but it is not suitable for multidimensional array of strings. I suggest that such an option: str[] strArray = [foo, bar, baz]; I don't see how adding a new builtin type `str` would solve anything. And why in C++ is running `std::vectorstd::string` ? Really in D can not do something like that? Maybe a new type will not solve anything, but there should be other ways to do in D analogue strings of C++. On Saturday, 13 June 2015 at 16:22:44 UTC, anonymous wrote: I don't understand what you're trying to say with that quote. I would not say `simpler`, and `basic`. I just forgot the right word, because my English is not good enough.
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 17:02:06 UTC, Dennis Ritchie wrote: On Saturday, 13 June 2015 at 16:20:46 UTC, anonymous wrote: [...] Yeah, that would be neat. But typing out .dup isn't that bad, and converting a `string[]` to a `char[][]` is simple: import std.conv: to; auto a = [foo].to!(char[][]); Yes, but it is not suitable for multidimensional array of strings. Please show how it is not. Seems to work just fine. [...] And why in C++ is running `std::vectorstd::string` ? Really in D can not do something like that? Maybe a new type will not solve anything, but there should be other ways to do in D analogue strings of C++. Your definitions of something like that and other ways are unreasonably narrow, in my opinion. Typing out .dup is D's way to do mutable strings. You just don't like it.
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
Type is probably possible, though conversion method will be simpler. You can even try to write a specialization of `to` for multidimentional arrays if it doesn't work.
char[][] to std::vectorstd::string - DIP or dmd-issue?
Hello, everyone! I like to work with arrays of strings like `string[] strArray`, but unfortunately, they are immutable. I do not like to work with arrays of strings such as `char[][] strArray`, because it is necessary to apply the method .dup each substring to make them work :) I understand that the type of `string[]` to D is a simple data type than `char[][]`, but it seems to me that the problem is solved in C++: std::vectorstd::string stdArray; I wish to propose the creation of new types of data D: str, wstr, dstr, which will be the analogs of C++ `std::vectorstd::string`. I do not know whether it is possible to create in the D, but I want to know where I write a sentence? Can I file a dmd-issue, or should I create a DIP, because it is too big improvement?
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 15:45:34 UTC, anonymous wrote: Before jumping to a solution, please elaborate on the perceived problem. I have a feeling that there is none. Do you like to write? char[][] strArray = [foo.dup, bar.dup, baz.dup]; I suggest that such an option: str[] strArray = [foo, bar, baz]; On Saturday, 13 June 2015 at 15:38:31 UTC, Dennis Ritchie wrote: Ie str, wstr, dstr be mutable counterparts immutable strings respectively str (mutable(char[])), wstr (mutable(wchar[])), dstr (mutable(dchar[])). In C++: std::vectorstd::string std::string in C++. str[], wstr[], dstr[] in C++: std::vectorstd::vectorstd::string std::vectorstring in C++.
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 08:21:50 -0400, ketmar ket...@ketmar.no-ip.org wrote: On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote: Is there a way to compile for multiple conditions? Tried all these: version(One | Two){ } version(One || Two){ } version(One Two){ } version(One) | version(Two){ } version(One) || version(Two){ } version(One) version(Two){ } Bit nope. Walter is against that, so we'll not have it, despite the triviality of the patch. Any idea what the rationale was for not allowing it? Bit
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 15:45:34 UTC, anonymous wrote: Huh? You mean with string literals? That would be a rather silly reason to avoid `char[]`. Please show an example of .dup you'd like to avoid. Yes, string literals. I understand that the type of `string[]` to D is a simple data type than `char[][]`, Are you saying that `string[]` is simpler than `char[][]`? That's not true: `string` is an alias for `immutable(char)[]`, so `string[]` is the same as `immutable(char)[][]`. On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote: But really, a string is immutable. There's not a way around that. A string is the most basic level of array primitive, not even mutable arrays of non-char types have that, and it's an annoyance. From there, you have to build the data out of ROM into the heap. http://forum.dlang.org/post/mjctql$j19$1...@digitalmars.com
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 13:49:49 +, anonymous wrote: Taking it one step further: template Version(string name) { mixin( version(~name~) enum Version = true; else enum Version = false; ); } static if(Version!One || Version!Two) { ... } very elegant. signature.asc Description: PGP signature
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 15:58:44 UTC, Dennis Ritchie wrote: On Saturday, 13 June 2015 at 15:45:34 UTC, anonymous wrote: Before jumping to a solution, please elaborate on the perceived problem. I have a feeling that there is none. Do you like to write? char[][] strArray = [foo.dup, bar.dup, baz.dup]; Ok. That's all you're on about? Basically you'd like this: char[] s = foo; and this: char[][] a = [[foo]]; etc. Yeah, that would be neat. But typing out .dup isn't that bad, and converting a `string[]` to a `char[][]` is simple: import std.conv: to; auto a = [foo].to!(char[][]); I suggest that such an option: str[] strArray = [foo, bar, baz]; I don't see how adding a new builtin type `str` would solve anything.
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 16:09:58 UTC, Dennis Ritchie wrote: On Saturday, 13 June 2015 at 15:45:34 UTC, anonymous wrote: [...] Are you saying that `string[]` is simpler than `char[][]`? That's not true: `string` is an alias for `immutable(char)[]`, so `string[]` is the same as `immutable(char)[][]`. On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote: But really, a string is immutable. There's not a way around that. A string is the most basic level of array primitive, not even mutable arrays of non-char types have that, and it's an annoyance. From there, you have to build the data out of ROM into the heap. http://forum.dlang.org/post/mjctql$j19$1...@digitalmars.com I don't understand what you're trying to say with that quote.
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 12:01:29 -0400, bitwise wrote: nope. Walter is against that, so we'll not have it, despite the triviality of the patch. Any idea what the rationale was for not allowing it? i don't remember. that murmuring about it makes the code harder to read goes beyond me, so it's hard to remember. signature.asc Description: PGP signature
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 12:20:40 -0400, ketmar ket...@ketmar.no-ip.org wrote: On Sat, 13 Jun 2015 13:49:49 +, anonymous wrote: Taking it one step further: template Version(string name) { mixin( version(~name~) enum Version = true; else enum Version = false; ); } static if(Version!One || Version!Two) { ... } very elegant. Elegant indeed, but I think my pull request would be frowned upon if I tried to use this in druntime. Bit
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 15:21:19 UTC, Dennis Ritchie wrote: I wish to propose the creation of new types of data D: str, wstr, dstr, which will be the analogs of C++ `std::vectorstd::string`. Ie str, wstr, dstr be mutable counterparts immutable strings respectively str (mutable(char[])), wstr (mutable(wchar[])), dstr (mutable(dchar[])). In C++: std::vectorstd::string str[], wstr[], dstr[] in C++: std::vectorstd::vectorstd::string
__traits getMember is context sensetive?
Hey, i am trying to wrap my head around __traits. One thing i just do not understand is following: struct S{ string member1; int member2; } void main(string[] args) { foreach(typeStr; __traits(allMembers, S)) { auto tp = __traits(getMember, S, typeStr); static if (__traits(isArithmetic, tp)) writeln(typeStr ~ is Arithmetic); } } Does not compile. main.d(15): Error: need 'this' for 'member1' of type 'string' But if the inner part of the foreach-loop is changed to: static if (__traits(isArithmetic, __traits(getMember, S, typeStr))) writeln(typeStr ~ is Arithmetic); it compiles and does exactly what i expect it to do. If i understand it correctly __traits(getMember returns a reference to that member, so i get why i shouldn't be able to use it with the class instead of an instance of a class. But why does it work if it is nested inside a __traits call?
Re: appender!(dchar[]) put fail
The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work. But I can see in the example of array.appander(http://dlang.org/phobos/std_array.html#appender) int[] a = [ 1, 2 ]; auto app2 = appender(a); app2.put(3); app2.put([ 4, 5, 6 ]); --- appender accepts another array. Why this is not same with dchar ?
Re: Conditional Compilation Multiple Versions
On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote: Is there a way to compile for multiple conditions? Tried all these: version(One | Two){ } version(One || Two){ } version(One Two){ } version(One) | version(Two){ } version(One) || version(Two){ } version(One) version(Two){ } Bit nope. Walter is against that, so we'll not have it, despite the triviality of the patch. signature.asc Description: PGP signature
Re: __traits getMember is context sensetive?
On Saturday, 13 June 2015 at 10:26:06 UTC, Marc Schütz wrote: On Saturday, 13 June 2015 at 10:01:45 UTC, JDemler wrote: Hey, i am trying to wrap my head around __traits. One thing i just do not understand is following: struct S{ string member1; int member2; } void main(string[] args) { foreach(typeStr; __traits(allMembers, S)) { auto tp = __traits(getMember, S, typeStr); static if (__traits(isArithmetic, tp)) writeln(typeStr ~ is Arithmetic); } } Does not compile. main.d(15): Error: need 'this' for 'member1' of type 'string' But if the inner part of the foreach-loop is changed to: static if (__traits(isArithmetic, __traits(getMember, S, typeStr))) writeln(typeStr ~ is Arithmetic); it compiles and does exactly what i expect it to do. If i understand it correctly __traits(getMember returns a reference to that member, so i get why i shouldn't be able to use it with the class instead of an instance of a class. But why does it work if it is nested inside a __traits call? Try `alias` instead of `auto`: struct S{ string member1; int member2; } alias I(Args...) = Args; void main(string[] args) { import std.stdio; foreach(typeStr; __traits(allMembers, S)) { alias tp = I!(__traits(getMember, S, typeStr)); static if (__traits(isArithmetic, tp)) writeln(typeStr ~ is Arithmetic); } } `auto` declares a variable, which in this case will probably contain a delegate to that member. The workaround with `I` is needed because of a syntactic limitation: `alias tp = __traits(...);` is currently not allowed by the grammar. Thank you. I tried alias but encountered the limitation mentioned.
appender!(dchar[]) put fail
I have two strings(stringB,stringC) which I need to repeat(bCount times, cCountTimes) and then chain. auto charAppender = appender!(dchar[]); auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); This compiles and works ok, But when I try to append new string to charAppender : charAppender.put(totalStr); Error: template std.array.join cannot deduce function from argument types I tried: charAppender.put(totalStr.array()); charAppender.data.chain(totalStr); charAppender.data.chain(totalStr.array()); etc... I always get compile errors. Do you have any idea or fix about that? Also what is the difference between algorithm.joiner without seperator and range.chain? As requested before, this time I will copy full code, int[dchar] mapA; int includeCounter(T)(T tuple) { int curMax = 10; foreach ( elem ; tuple ) { int numberInA = 0; if (elem[0] in mapA) numberInA = mapA[elem[0]] ; else { curMax = 0; break; } if ( numberInA elem[1] ) { curMax = 0; break; } else { auto newCount = numberInA / elem[1]; if ( newCount curMax ) curMax = newCount; } } if (curMax 0) { foreach ( elem ; tuple ) { mapA[elem[0]] -= curMax; } } return curMax; } void readInput() { size_t lineSize; auto stringA = stdin.readln.chomp().map!( a = to!dchar(a)).array(); auto stringB = stdin.readln.chomp().map!( a = to!dchar(a)).array(); auto stringC = stdin.readln.chomp().map!( a = to!dchar(a)).array(); foreach ( elem ; stringA) mapA[elem]++; auto tupleB = stringB.group(); auto tupleC = stringC.group(); auto bCount = includeCounter( tupleB ); auto cCount = includeCounter( tupleC ); auto charAppender = appender!(dchar[]); foreach ( elem ; mapA.keys) { int* count = mapA[elem]; if ( *count 0) { while((*count)--) charAppender.put(elem) ; } } auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); charAppender.put(totalStr); } void main( string[] args ) { readInput(); }
Re: __traits getMember is context sensetive?
On Sat, 13 Jun 2015 10:36:39 +, John Colvin wrote: *for some reason it's not public, but it's very short and simple: it's funny how many useful things are there in Phobos, carefully hidden from user. i believe each D book should include an advice like this: to fully learn what you can do in D out-of-the-box, carefully read druntime and Phobos sources. you'll find many gems there. but tell noone about your discoveries, neophytes should not get the Secret Knowledge! ;-) signature.asc Description: PGP signature
Re: How to realize copyable/postblit class
On Saturday, 13 June 2015 at 05:20:42 UTC, SimonN wrote: Hi, I have a few classes with need for deeper copying. I don't want a bitwise copy necessarily. Ideally, I'd implement this(this). I've thought about changing them to struct. However, the type feels much more like a D class than a D struct. It's often passed by reference, and it's not plain old data. Changing it to struct for the sole benefit of this(this) seems to be a bad tradeoff. (Use case: Backing up game states in a for savestating/networking.) I've resorted to a C++-style copy constructor: this(T rhs) { myvalue = rhs.myvalue; myarray = rhs.myarray.dup; // ... } Downside: Boilerplate, each member appears once in the declarations, a second time in the copy constructor. Alternative approaches seem to implement T T.dup() or T T.clone(). Apparently, one has to pick one of these equally good approaches, and stick with it throughout a codebase. It seems good to implement it only for the classes that need it, to minimize boilerplate. Is that the state of the art? -- Simon perhaps: class A { struct S { //class contents this(this){ /*any extra post-copy fixeup you need*} } S s; //to avoid having to type A.s.myMember alias s this; //or could use std.typecons.Proxy this(A rhs) { s = rhs.s; } }
Re: __traits getMember is context sensetive?
On Saturday, 13 June 2015 at 10:01:45 UTC, JDemler wrote: Hey, i am trying to wrap my head around __traits. One thing i just do not understand is following: struct S{ string member1; int member2; } void main(string[] args) { foreach(typeStr; __traits(allMembers, S)) { auto tp = __traits(getMember, S, typeStr); static if (__traits(isArithmetic, tp)) writeln(typeStr ~ is Arithmetic); } } Does not compile. main.d(15): Error: need 'this' for 'member1' of type 'string' But if the inner part of the foreach-loop is changed to: static if (__traits(isArithmetic, __traits(getMember, S, typeStr))) writeln(typeStr ~ is Arithmetic); it compiles and does exactly what i expect it to do. If i understand it correctly __traits(getMember returns a reference to that member, so i get why i shouldn't be able to use it with the class instead of an instance of a class. But why does it work if it is nested inside a __traits call? Try `alias` instead of `auto`: struct S{ string member1; int member2; } alias I(Args...) = Args; void main(string[] args) { import std.stdio; foreach(typeStr; __traits(allMembers, S)) { alias tp = I!(__traits(getMember, S, typeStr)); static if (__traits(isArithmetic, tp)) writeln(typeStr ~ is Arithmetic); } } `auto` declares a variable, which in this case will probably contain a delegate to that member. The workaround with `I` is needed because of a syntactic limitation: `alias tp = __traits(...);` is currently not allowed by the grammar.
Re: __traits getMember is context sensetive?
On Saturday, 13 June 2015 at 10:01:45 UTC, JDemler wrote: Hey, i am trying to wrap my head around __traits. One thing i just do not understand is following: struct S{ string member1; int member2; } void main(string[] args) { foreach(typeStr; __traits(allMembers, S)) { auto tp = __traits(getMember, S, typeStr); static if (__traits(isArithmetic, tp)) writeln(typeStr ~ is Arithmetic); } } Does not compile. main.d(15): Error: need 'this' for 'member1' of type 'string' But if the inner part of the foreach-loop is changed to: static if (__traits(isArithmetic, __traits(getMember, S, typeStr))) writeln(typeStr ~ is Arithmetic); it compiles and does exactly what i expect it to do. If i understand it correctly __traits(getMember returns a reference to that member, so i get why i shouldn't be able to use it with the class instead of an instance of a class. But why does it work if it is nested inside a __traits call? auto tp is treating a runtime variable, but you don't have an actual instance of S. What you want is an alias of the symbol without creating an instance. Unfortunately alias tp = __traits(getMember, S, typeStr); doesn't work, but if you steal* Alias from std.typetuple(or std.meta, if you're running a very recent dmd build) then you can do alias tp = Alias!(__traits(getMember, S, typeStr)); and then it will work for you. *for some reason it's not public, but it's very short and simple: template Alias(alias a) { static if (__traits(compiles, { alias x = a; })) alias Alias = a; else static if (__traits(compiles, { enum x = a; })) enum Alias = a; else static assert(0, Cannot alias ~ a.stringof); } // types and tuples template Alias(a...) { alias Alias = a; } unittest { enum abc = 1; static assert(__traits(compiles, { alias a = Alias!(123); })); static assert(__traits(compiles, { alias a = Alias!(abc); })); static assert(__traits(compiles, { alias a = Alias!(int); })); static assert(__traits(compiles, { alias a = Alias!(1,abc,int); })); }
Re: appender!(dchar[]) put fail
On Saturday, 13 June 2015 at 10:45:58 UTC, kerdemdemir wrote: I have two strings(stringB,stringC) which I need to repeat(bCount times, cCountTimes) and then chain. auto charAppender = appender!(dchar[]); auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); This compiles and works ok, But when I try to append new string to charAppender : charAppender.put(totalStr); Error: template std.array.join cannot deduce function from argument types I tried: charAppender.put(totalStr.array()); charAppender.data.chain(totalStr); charAppender.data.chain(totalStr.array()); etc... I always get compile errors. Do you have any idea or fix about that? Also what is the difference between algorithm.joiner without seperator and range.chain? As requested before, this time I will copy full code, int[dchar] mapA; int includeCounter(T)(T tuple) { int curMax = 10; foreach ( elem ; tuple ) { int numberInA = 0; if (elem[0] in mapA) numberInA = mapA[elem[0]] ; else { curMax = 0; break; } if ( numberInA elem[1] ) { curMax = 0; break; } else { auto newCount = numberInA / elem[1]; if ( newCount curMax ) curMax = newCount; } } if (curMax 0) { foreach ( elem ; tuple ) { mapA[elem[0]] -= curMax; } } return curMax; } void readInput() { size_t lineSize; auto stringA = stdin.readln.chomp().map!( a = to!dchar(a)).array(); auto stringB = stdin.readln.chomp().map!( a = to!dchar(a)).array(); auto stringC = stdin.readln.chomp().map!( a = to!dchar(a)).array(); foreach ( elem ; stringA) mapA[elem]++; auto tupleB = stringB.group(); auto tupleC = stringC.group(); auto bCount = includeCounter( tupleB ); auto cCount = includeCounter( tupleC ); auto charAppender = appender!(dchar[]); foreach ( elem ; mapA.keys) { int* count = mapA[elem]; if ( *count 0) { while((*count)--) charAppender.put(elem) ; } } auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); charAppender.put(totalStr); } void main( string[] args ) { readInput(); } The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work.
Re: Qualified destructors / immutable objects
Is there an existing issue on issue.dlang.org? If not can you report it https://issues.dlang.org/show_bug.cgi?id=10376
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 18:15:30 UTC, Dennis Ritchie wrote: Actually, I will file issue `std.conv` in Phobos to add such specifications. It will suit me. *specializations
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 17:39:25 UTC, Kagamin wrote: Type is probably possible, though conversion method will be simpler. You can even try to write a specialization of `to` for multidimentional arrays if it doesn't work. It appears the problem can be solved by creating specifications .to!strArray, which will determine the dimension of the array and convert it to char[][][][]... Actually, I will file issue `std.conv` in Phobos to add such specifications. It will suit me. Thanks to all. I just didn't know that such a conversion is running.
new pragma(inline) syntax
Are `foo` and `bar` always inlined? struct S { pragma(inline, true): void foo(T)(T t) {} void bar(T)(T t) {} }
Re: new pragma(inline) syntax
On Saturday, 13 June 2015 at 19:13:20 UTC, Ilya Yaroshenko wrote: Are `foo` and `bar` always inlined? struct S { pragma(inline, true): void foo(T)(T t) {} void bar(T)(T t) {} } I am confused becuase they are templates.
Re: char[][] to std::vectorstd::string - DIP or dmd-issue?
On Saturday, 13 June 2015 at 17:37:31 UTC, anonymous wrote: Please show how it is not. Seems to work just fine. OK. Still, this method works: char[][][][][][] strArr = [foo, baz], [bar, tor.to!(char[][][][][])]; But I don't want to write this `.to!(char[][][][][])`. On Saturday, 13 June 2015 at 17:37:31 UTC, anonymous wrote: Your definitions of something like that and other ways are unreasonably narrow, in my opinion. Typing out .dup is D's way to do mutable strings. You just don't like it. Yes, I don't like it.
Re: How to realize copyable/postblit class
On Saturday, 13 June 2015 at 08:52:59 UTC, John Colvin wrote: perhaps: class A { struct S { // ... } S s; alias s this; this(A rhs) { s = rhs.s; } } I'm using this now, and it doesn't feel like a workaround too much. For something with 5 value fields, it's already shorter than the original solution. Thanks! :-) -- Simon