Re: Template recursion error on table struct
WARNING: Do not try to compile this code. Your computer may be unresponsive for a while. :) On 03/25/2016 02:54 PM, data pulverizer wrote: > I am attempting to create a table struct with generic column types using > templates. However, the template arguments are not types; rather, aliases. > template ColumnTable(T...){ > struct ColumnTable{ > private: > typeof(T) data; > string[] names; > struct Range{ > size_t begin; > size_t end; > } > // This function is the source of the issue > auto subTable(Range rowRange, Range columnRange)(){ > auto new_data = data[columnRange.begin .. columnRange.end]; > auto output = ColumnTable!(new_data)(new_data); // This is the > problem new_data is a local variable. So, this instantiation of ColumnTable is with that symbol. > void main(){ > string[] names = ["tariq", "sharma", "peter", "rakel"]; > double[] salary = [44.5, 32.2, 40.1, 28.1]; > int[] age = [24, 20, 22, 25, 19]; > writeln(ColumnTable!(names, salary, age)(names, salary, age)); > } Likewise, that instantiation of ColumnTable is with the symbols 'names', 'salary', and 'age'. Is that what you want? Or do you want to instantiate with their types? Can you explain some more what you are trying to do. Ali
Re: byChunk odd behavior?
On Friday, 25 March 2016 at 08:01:04 UTC, cym13 wrote: // This consume auto buffer3 = range.take(4).array; assert(buffer3 == [0, 5, 10, 15]); } Thanks for your help. However the last statement is incorrect. I am in fact looking for a version of 'take' that consumes the InputRange. You can see it by doing a second take afterwards. auto buffer3 = range.take(4).array; assert(buffer3 == [0, 5, 10, 15]); auto buffer4 = range.take(4).array; assert(buffer4 == [0, 5, 10, 15]); I haven't clearly explained my main goal. I have a large binary file that I need to deserialize. It's not my file and it's in a custom but simple format, so I would prefer not to depend on a third party serializer library but I will look into that. I was thinking around the lines of: 1. Open file 2. Map a byChunk.joiner to read by chunks and present an iterator interface 3. Read data with std.bitmanip/read functions Step 3. works fine as long as items are single scalar values. bitmanip doesn't have array readers. Obviously, I could loop but then I thought that for the case of a ubyte[], there would be a shortcut that I don't know about. Thanks, --h
Re: Random Access I/O
On Saturday, 26 March 2016 at 00:10:23 UTC, Chris Williams wrote: None of the access modes for std.stdio.File seem to allow that. Any usage of the "w" mode causes my code to consider the file empty if it pre-exists (though, it doesn't always actually truncate the disk on file?) Mode "a+" or "r+" for append+read or read+write will do it, same as in C. If I was coding in C, I would use open() as it gives more options for access: This function is in `import core.sys.posix.fcntl;` (the documentation is lax on this but generally when you see a Posix function in C that is #include, you can get it in D with `import core.sys.posix.X`.
Re: Initializing global delegate variable - bug or on purpose?
On Friday, 25 March 2016 at 23:40:37 UTC, data pulverizer wrote: On Friday, 25 March 2016 at 20:54:28 UTC, Atila Neves wrote: int delegate(int) dg = (i) => i * 2; Error: non-constant nested delegate literal expression __lambda3 int delegate(int) dg; static this() { dg = i => i * 2; // ok } Am I doing anything wrong? Atila Hmm, looks like your first delegate is a function type and the second is a function instance. So the first version written like this ... import std.stdio; alias dg = int delegate(int); dg make_dg(){ return i => i*2; } void main(){ auto my_dg = make_dg(); writeln(my_dg(3)); } will work. In fact for the second case I'd probably need to see a working struct/class prototype to make a firm comment on it.
Re: Random Access I/O
On Saturday, 26 March 2016 at 00:10:23 UTC, Chris Williams wrote: I need to be able to perform random access I/O against a file, creating a new file if it doesn't exist, or opening as-is (no truncation) if it already exists. None of the access modes for std.stdio.File seem to allow that. Any usage of the "w" mode causes my code to consider the file empty if it pre-exists (though, it doesn't always actually truncate the disk on file?) If I was coding in C, I would use open() as it gives more options for access: http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html However, I don't see this exposed in phobos anywhere? The Programming in D book chapter on Files http://ddili.org/ders/d.en/files.html will help. I think the "std.stdio.File struct" section on the same page has what you need. Also, take a look at http://dlang.org/phobos/std_stdio.html#.File.open.
Random Access I/O
I need to be able to perform random access I/O against a file, creating a new file if it doesn't exist, or opening as-is (no truncation) if it already exists. None of the access modes for std.stdio.File seem to allow that. Any usage of the "w" mode causes my code to consider the file empty if it pre-exists (though, it doesn't always actually truncate the disk on file?) If I was coding in C, I would use open() as it gives more options for access: http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html However, I don't see this exposed in phobos anywhere?
Re: Initializing global delegate variable - bug or on purpose?
On Friday, 25 March 2016 at 20:54:28 UTC, Atila Neves wrote: int delegate(int) dg = (i) => i * 2; Error: non-constant nested delegate literal expression __lambda3 int delegate(int) dg; static this() { dg = i => i * 2; // ok } Am I doing anything wrong? Atila Hmm, looks like your first delegate is a function type and the second is a function instance. So the first version written like this ... import std.stdio; alias dg = int delegate(int); dg make_dg(){ return i => i*2; } void main(){ auto my_dg = make_dg(); writeln(my_dg(3)); } will work.
Re: Strange behavior in console with UTF-8
On Friday, 25 March 2016 at 13:58:44 UTC, Steven Schveighoffer wrote: On 3/24/16 8:54 PM, Jonathan Villa wrote: [...] D's File i/o uses C's FILE * i/o system. At least on Windows, this has literally zero support for wchar (you can set stream width, and the library just ignores it). What is likely happening is that it is putting the char code units into wchar buffer directly, which is not what you want. I am not certain of this cause, but I would steer clear of any i/o that is not char-based. What you can do is read into a char buffer, and then re-encode using std.conv.to to get wchar strings if you need that. -Steve It's the same Ali suggested (if I get it right) and the behaviour its the same. It just get to send a UTF8 char to reproduce the mess, independently of the char type you send. JV
Re: Template recursion error on table struct
p.s. I realise that the ColumnTable call is a little ponderous but I tidy it up in a convenience wrapper function: auto CreateDataTable(Args...)(){ string[] names; foreach(i, arg; Args){ names ~= Args[i].stringof; } auto df = ColumnTable!(Args)(Args); df.setNames(names); return df; } // auto myTable = CreateDataTable!(names, salary, age)();
Template recursion error on table struct
I am attempting to create a table struct with generic column types using templates. The subTable() member function subsets the table, however I am getting a template recursion error. I know where the problem is from, I don't know how to resolve it. I am modelling it after the matrix example in Ali Çehreli book: http://ddili.org/ders/d.en/templates_more.html import std.stdio; template ColumnTable(T...){ struct ColumnTable{ private: typeof(T) data; string[] names; struct Range{ size_t begin; size_t end; } // This function is the source of the issue auto subTable(Range rowRange, Range columnRange)(){ auto new_data = data[columnRange.begin .. columnRange.end]; auto output = ColumnTable!(new_data)(new_data); // This is the problem string[] new_names = names[columnRange.begin .. columnRange.end]; output.setNames(new_names); return output; } public: this(T...)(T args){ data = args; foreach(i, arg; T){ names ~= args[i].stringof; } } void setNames(string[] names){ this.names = names; } void test(){ writeln(subTable!(Range(0, 2), Range(0, 2))()); } } } void main(){ string[] names = ["tariq", "sharma", "peter", "rakel"]; double[] salary = [44.5, 32.2, 40.1, 28.1]; int[] age = [24, 20, 22, 25, 19]; writeln(ColumnTable!(names, salary, age)(names, salary, age)); }
Initializing global delegate variable - bug or on purpose?
int delegate(int) dg = (i) => i * 2; Error: non-constant nested delegate literal expression __lambda3 int delegate(int) dg; static this() { dg = i => i * 2; // ok } Am I doing anything wrong? Atila
Re: rawWrite of a struct suggestions
On 03/25/2016 11:32 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Friday, 25 March 2016 at 18:25:28 UTC, Charles Hixson wrote: But when I try to cast a Chnk to a ubyte[], I get an error, and rawWrite takes a generic array of anything... you should be able to rawWrite((&your_object)[0 .. 1]) Thanks, that compiled. It's running a test now...and I'm leaving it for a few hours.
Re: rawWrite of a struct suggestions
On Friday, 25 March 2016 at 18:25:28 UTC, Charles Hixson wrote: But when I try to cast a Chnk to a ubyte[], I get an error, and rawWrite takes a generic array of anything... you should be able to rawWrite((&your_object)[0 .. 1])
rawWrite of a struct suggestions
I've got a simple struct: structChnk { ulongid; char[20]wrd; ubytelength; ...<--various utility functions and constructors } That I'm trying to write to a file. I want to use an unformatted read/write because I want this to be a random access file. But when I try to cast a Chnk to a ubyte[], I get an error, and when I try to to!ubyte[] it I get a slightly different error:: Error: template instance isRawStaticArray!() does not match template declaration isRawStaticArray(T, A...) I don't want to copy it twice each time I read or write it, as I would if, e.g., I used OutBuffer. How should I approach this? Do I need to use fread/fwrite? I'm sure I used to be able to pass a pointer and length, but I can't find that option anymore.
Re: getOverloads, but also include all the imported members
On Thursday, 24 March 2016 at 15:52:49 UTC, Adam D. Ruppe wrote: On Thursday, 24 March 2016 at 15:07:09 UTC, Yuxuan Shui wrote: Is there a way to do this automatically? No. You have to decide to bring them together if you want them to overload. Oh, sorry, this is not what I meant. What I wanted to know is if it's possible to automate this aliasing process, by using for example templates?
Re: Strange behavior in console with UTF-8
On 3/24/16 8:54 PM, Jonathan Villa wrote: I prefer to post this thing here because it could that I'm doing something wrong. I'm using std.stdio -> readln() to read whatever I'm typing in the console. BUT, if the line contains some UTF-8 characters, the data obtained is EMPTY and module runnable; import std.stdio; import std.string : chomp; import std.experimental.logger; void doSomethingElse(wchar[] data) { writeln("hello!"); } int main(string[] args) { /* Some fix I found to fix UTF-8 related problems, I'm using Windows 10 */ version(Windows) { import core.sys.windows.windows; if (SetConsoleCP(65001) == 0) throw new Exception("failure"); if (SetConsoleOutputCP(65001) == 0) throw new Exception("failure"); } FileLogger fl = new FileLogger("log.log"); wchar[] readerBuffer; readln(readerBuffer); readerBuffer = chomp(readerBuffer); fl.info(readerBuffer.length); /* <- if the readed string contains at least one UTF-8 char this prints 0, else it prints its length */ if (readerBuffer != "exit"w) doSomethingElse(readerBuffer); /* Also, all the following code doesn't run as expected, the program doesn't wait for you, it executes readln() even without pressing/sending a key */ readln(readerBuffer); fl.info(readerBuffer.length); readln(readerBuffer); fl.info(readerBuffer.length); readln(readerBuffer); fl.info(readerBuffer.length); readln(readerBuffer); fl.info(readerBuffer.length); readln(readerBuffer); fl.info(readerBuffer.length); return 0; } The real code is bigger but this describes the bug. Also, if it needs to print UTF-8 there's no problem. My main problem is that the line is gonna be sended through a TCP socket and I wanna make it work with UTF-8. I'm using WCHAR instead of CHAR with the hope to get less problems in the future. I you comment the fixed Windows code, the program crashes http://prntscr.com/ajmy14 Also I tried stdin.flush() right after the first readln() but nothing seems to fix it. I'm doing something wrong? many thanks. D's File i/o uses C's FILE * i/o system. At least on Windows, this has literally zero support for wchar (you can set stream width, and the library just ignores it). What is likely happening is that it is putting the char code units into wchar buffer directly, which is not what you want. I am not certain of this cause, but I would steer clear of any i/o that is not char-based. What you can do is read into a char buffer, and then re-encode using std.conv.to to get wchar strings if you need that. -Steve
Re: Struct array assignment behaviour using example from Programming in D, chapter 78
On Friday, 25 March 2016 at 08:53:20 UTC, Ali Çehreli wrote: On 03/25/2016 12:00 AM, data pulverizer wrote: > On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote: >> On 03/24/2016 10:24 AM, data pulverizer wrote: >> > I have been playing with the matrix example given at the end >> of chapter >> > 78 of Ali Çehreli's >> >> For reference, it's "Multi-dimensional operator overloading example" >> here: >> >> http://ddili.org/ders/d.en/templates_more.html >> >> >having problems with overloading the opAssign operator. > Thank you. Let me try to ask the question again. The problem I am > experiencing is to do with opIndexAssign(). > > I added the following public operators: > > Matrix opAssign(int[][] arr) > { > writeln(__FUNCTION__); > this.rows = arr; > return this; > } The problem is due to the aliasing of 'rows' members of Matrix objects. subMatrix is supposed to be a reference into some elements of an existing Matrix. As soon as we do the above assignment, this Matrix (which may be a subMatrix in a specific context) breaks lose from its actual Matrix elements. We need to implement the function above "in place": Matrix opAssign(int[][] arr) { writeln(__FUNCTION__); if (rows.length < arr.length) { rows.length = arr.length; } foreach (i, row; arr) { const newLength = row.length; if (rows[i].length < newLength) { rows[i].length = newLength; } rows[i][0..newLength] = row[]; } return this; } (There must be an existing function that does that.) > Matrix opAssign(Matrix mat) > { > writeln(__FUNCTION__); > this.rows = mat.rows; Same thing applies above: We need to assign to this.rows in place (which is easier by taking advantage of the previous function): this = mat.rows; > return this; > } No changes needed for the other two functions but I would 'return this' instead of 'return subMatrix' for them as well. Ali That's great! Thank you very much for the fix and extra suggestions, and for your patience putting up with my poorly formulated question! Looks like I need to go and read all the structs and operators chapters thoroughly!
Re: Struct array assignment behaviour using example from Programming in D, chapter 78
On 03/25/2016 12:00 AM, data pulverizer wrote: > On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote: >> On 03/24/2016 10:24 AM, data pulverizer wrote: >> > I have been playing with the matrix example given at the end >> of chapter >> > 78 of Ali Çehreli's >> >> For reference, it's "Multi-dimensional operator overloading example" >> here: >> >> http://ddili.org/ders/d.en/templates_more.html >> >> >having problems with overloading the opAssign operator. > Thank you. Let me try to ask the question again. The problem I am > experiencing is to do with opIndexAssign(). > > I added the following public operators: > > Matrix opAssign(int[][] arr) > { > writeln(__FUNCTION__); > this.rows = arr; > return this; > } The problem is due to the aliasing of 'rows' members of Matrix objects. subMatrix is supposed to be a reference into some elements of an existing Matrix. As soon as we do the above assignment, this Matrix (which may be a subMatrix in a specific context) breaks lose from its actual Matrix elements. We need to implement the function above "in place": Matrix opAssign(int[][] arr) { writeln(__FUNCTION__); if (rows.length < arr.length) { rows.length = arr.length; } foreach (i, row; arr) { const newLength = row.length; if (rows[i].length < newLength) { rows[i].length = newLength; } rows[i][0..newLength] = row[]; } return this; } (There must be an existing function that does that.) > Matrix opAssign(Matrix mat) > { > writeln(__FUNCTION__); > this.rows = mat.rows; Same thing applies above: We need to assign to this.rows in place (which is easier by taking advantage of the previous function): this = mat.rows; > return this; > } No changes needed for the other two functions but I would 'return this' instead of 'return subMatrix' for them as well. Ali
Re: byChunk odd behavior?
On Thursday, 24 March 2016 at 07:52:27 UTC, Hanh wrote: On Wednesday, 23 March 2016 at 19:07:34 UTC, cym13 wrote: In Scala, 'take' consumes bytes from the iterator. So the same code would be buffer = range.take(N).toArray Then just do that! import std.range, std.array; auto buffer = range.take(N).array; auto example = iota(0, 200, 5).take(5).array; assert(example == [0, 5, 10, 15, 20]); Well, that's what I do in the first post but you can't call it twice with an InputRange. auto buffer1 = range.take(4).array; // ok range.popFrontN(4); // not ok auto buffer2 = range.take(4).array; // not ok Please, take some time to reread cy's answer above. void main(string[] args) { import std.range; import std.array; import std.algorithm; auto range = iota(0, 25, 5); // Will not consume (forward ranges only) // // Note however that range elements are not stored in any way by default // so reusing the range will also need you to recompute them each time! auto buffer1 = range.save.take(4).array; assert(buffer1 == [0, 5, 10, 15]); // The solution to the recomputation problème, and often the best way to // handle range reuse is to store them in an array // // This is reusable at will with no redundant computation auto arr = range.save.array; assert(arr == [0, 5, 10, 15, 20]); // And it has a range interface too auto buffer2 = arr.take(4).array; assert(buffer2 == [0, 5, 10, 15]); // This consume auto buffer3 = range.take(4).array; assert(buffer3 == [0, 5, 10, 15]); }
Re: Struct array assignment behaviour using example from Programming in D, chapter 78
On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote: On 03/24/2016 10:24 AM, data pulverizer wrote: > I have been playing with the matrix example given at the end of chapter > 78 of Ali Çehreli's For reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.html >having problems with overloading the opAssign operator. > > rows is a private int[][] in a Matrix struct. > > I have added the following ... > > Matrix opAssign(int[][] arr) > { > this.rows = arr; > // rows = arr // does not work either ... > return this; > } > > However this does not work (no error occurs, it just doesn't do > anything) How are you testing it? The following worked for me: 1) Added that opAssign() to the struct. (Verified that it gets called.) 2) Tested with the following code: auto m2 = Matrix(); auto rows = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]; m2 = rows; writeln(m2); (I've tested with a dynamically generated 'rows' as well.) Ali Thank you. Let me try to ask the question again. The problem I am experiencing is to do with opIndexAssign(). I added the following public operators: Matrix opAssign(int[][] arr) { writeln(__FUNCTION__); this.rows = arr; return this; } Matrix opAssign(Matrix mat) { writeln(__FUNCTION__); this.rows = mat.rows; return this; } Matrix opIndexAssign(A...)(int[][] arr, A arguments) if(A.length <= 2){ writeln(__FUNCTION__); Matrix subMatrix = opIndex(arguments); assert(((arr.length == subMatrix.nrow()) & (arr[0].length == subMatrix.ncol())), "Array dimension do not match matrix replacement.\n"); /*foreach(i, row; subMatrix.rows){ row[] = arr[i]; }*/ subMatrix = arr; // Does not work return subMatrix; } Matrix opIndexAssign(A...)(Matrix mat, A arguments) if(A.length <= 2){ writeln(__FUNCTION__); Matrix subMatrix = opIndex(arguments); assert(((mat.nrow() == subMatrix.nrow()) & (mat.ncol() == subMatrix.ncol())), "Array dimension do not match matrix replacement.\n"); /*foreach(i, row; subMatrix.rows){ row[] = mat.rows[i]; }*/ subMatrix = mat; // Does not work return subMatrix; } void main(){ // Here we test opAssign [][]int auto a = Matrix(); a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; // this works writeln(a); // opIndexAssign int[][] a[0..2, 0..2] = [[88, 88], [88, 88]]; // this does not work writeln(a); auto b = Matrix(); // opAssign Matrix b = a; // this works writeln(b); b = [[88, 88, 88, 88], [88, 88, 88, 88], [88, 88, 88, 88], [88, 88, 88, 88]]; // opIndexAssign Matrix b[0..3, 0..3] = a; // this does not work writeln(b); } If you uncomment the foreach lines, the opIndexAssign() work.