Re: More type-flexible arrays?
p.s. faster weak typing solution is definitely possible if you'll narrow possible type set. but as i said, i'd not recommend to go this way. there can be dragon in the end. signature.asc Description: PGP signature
Re: More type-flexible arrays?
On 06/13/2015 11:12 PM, Ozan wrote: > Hallo! > > Is it possible to create arrays which has more then one type, Not possible. > f. ex. array[0] = 1; array[1] = "z"; array[2] = new clazz(), > > I tried "Variant", but it slow down heavily my app. Another option is OOP. Depending on the way they are used in the program, those different types have a common interface. It is possible to have an array of that interface: Foo[] foos; interface Foo { void commonFunction(); // ... } class clazz : Foo { // ... } However, fundamental types like int need to be boxed: class FundamentalFoo(T) : Foo { T value; // ... } If needed, you can specialize FundamentalFoo for int, string, etc. Ali
Re: More type-flexible arrays?
On Sun, 14 Jun 2015 06:12:29 +, Ozan wrote: > Hallo! > > Is it possible to create arrays which has more then one type, > f. ex. array[0] = 1; array[1] = "z"; array[2] = new clazz(), > > I tried "Variant", but it slow down heavily my app. it is possible. with Variant. ;-) chances are that you're doing something by the wrong way in your code. not syntactically wrong, but algorithmically wrong. why to you need such an array? weak typing is slow. strong typing is fast. seems that you are used to scripting languages with weak typing, and designed your algorithm with weak typing in mind. i think it's better to try to redesign your algorithm, not looking for faster weak typing solution. signature.asc Description: PGP signature
More type-flexible arrays?
Hallo! Is it possible to create arrays which has more then one type, f. ex. array[0] = 1; array[1] = "z"; array[2] = new clazz(), I tried "Variant", but it slow down heavily my app. Greetings, Ozan
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: __traits getMember is context sensetive?
oh, seems that i managed to make everything even less understandable... signature.asc Description: PGP signature
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
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: 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.
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: 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: 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: 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.
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){} ?
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: What is D's minimum requirements on Mac?
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)
Re: __traits getMember is context sensetive?
On Saturday, 13 June 2015 at 23:51:32 UTC, JDemler wrote: 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 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. Is there a workaround for that?
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: 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 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
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::vector - 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::vector - 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.
Re: char[][] to std::vector - 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: 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::vector - 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::vector` ? 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::vector - 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.
Re: char[][] to std::vector - 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::vector` ? 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: Serialization array of structure
Oh, sorry, the error was in another place.
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 12:20:40 -0400, ketmar 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: 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: 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: char[][] to std::vector - 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::vector - 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: char[][] to std::vector - 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
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::vector - 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: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 08:21:50 -0400, ketmar 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::vector - 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::vector std::string in C++. str[], wstr[], dstr[] in C++: std::vector > std::vector in C++.
Re: char[][] to std::vector - 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::vector stdArray; I wish to propose the creation of new types of data D: str, wstr, dstr, which will be the analogs of C++ `std::vector`. Before jumping to a solution, please elaborate on the perceived problem. I have a feeling that there is none.
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::vector - 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::vector`. Ie str, wstr, dstr be mutable counterparts immutable strings respectively str (mutable(char[])), wstr (mutable(wchar[])), dstr (mutable(dchar[])). In C++: std::vector str[], wstr[], dstr[] in C++: std::vector >
char[][] to std::vector - 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::vector stdArray; I wish to propose the creation of new types of data D: str, wstr, dstr, which will be the analogs of C++ `std::vector`. 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: 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: 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: 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: 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("c"d.dup); charAppender.put("test"d.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: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("c"d.dup); charAppender.put("test"d.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 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: 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 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: 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: 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.
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 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: __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.
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.
__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: 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; } }