Re: Parsing a UTF-16LE file line by line, BUG?
On Monday, 16 January 2017 at 14:47:23 UTC, Era Scarecrow wrote: static char[1024*4] buffer; //4k reusable buffer, NOT thread safe Maybe I'm wrong, but I think it's thread safe. Because static mutable non-shared variables are stored in TLS.
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 23:10:02 UTC, albert-j wrote: On Thursday, 26 January 2017 at 13:21:38 UTC, Dukc wrote: import std.stdio, std.algorithm, std.range, std.array; int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto sortedB = sort(b.dup); auto c = a . filter!(i => !sortedB.contains(i)) . array ; assert(c == [1, 2, 5, 7]); If arrays get large, this should be more efficient since it performs O(n * n.log) instead of O(n * n). It does look much faster than my solution. Will it also work correctly and fast for arrays of custom objects? How should opCmp() be defined if objects don't have a meaningful ordering? The order of elements in the original array does not matter. To me it looks rather slow. please benchmark!
Re: Parsing a UTF-16LE file line by line, BUG?
On Tuesday, 17 January 2017 at 11:40:15 UTC, Nestor wrote: Thanks, but unfortunately this function does not produce proper UTF8 strings, as a matter of fact the output even starts with the BOM. Also it doesn't handle CRLF, and even for LF terminated lines it doesn't seem to work for lines other than the first. I thought you wanted to get line by line of contents, which would then remain as UTF-16. Translating between the two types shouldn't be hard, probably to!string or a foreach with appending to code-units on chars would convert to UTF-8. Skipping the BOM is just a matter of skipping the first two bytes identifying it... I guess I have to code encoding detection, buffered read, and transcoding by hand, the only problem is that the result could be sub-optimal, which is why I was looking for a built-in solution. Maybe. Honestly I'm not nearly as familiar with the library or functions as I would love to be, so often home-made solutions seem more prevalent until I learn the lingo. A disadvantage of being self taught.
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 13:21:38 UTC, Dukc wrote: import std.stdio, std.algorithm, std.range, std.array; int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto sortedB = sort(b.dup); auto c = a . filter!(i => !sortedB.contains(i)) . array ; assert(c == [1, 2, 5, 7]); If arrays get large, this should be more efficient since it performs O(n * n.log) instead of O(n * n). It does look much faster than my solution. Will it also work correctly and fast for arrays of custom objects? How should opCmp() be defined if objects don't have a meaningful ordering? The order of elements in the original array does not matter.
Re: When I should create structures with new keywords?
On Thursday, 26 January 2017 at 19:30:54 UTC, Suliman wrote: But I still not understand where the data is location in first variant? It is stored in the file itself. The File struct is pretty small, it just provides access to the contents of the file, it doesn't actually hold that content itself.
When I should create structures with new keywords?
In the past I asked Adam about when I should use keyword `new` with structures and got next answer: "The File in the first one is put on the stack as a reference counted local object whereas the second one would be on the garbage collected heap, which often isn't what you want for files since you want to close them when you're done. Generally, D's structs often work best without the `new` keyword since they can be made in place." But I have read that stack size is very limited I tried to test two variants of reading big (20MB) text file: auto file = File("test.txt", "r"); and auto file = new File("test.txt", "r"); Tests does not show any significant difference in performance. But I still not understand where the data is location in first variant?
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote: What is the D idiom for removing array elements that are present in another array? Is this the right/fastest way? int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto c = a.remove!(x => b.canFind(x)); assert(c == [1, 2, 5, 7]); If you don't care about array a being mutated, then I think what you have is best (although I would suggest that if you don't care about a being mutated, just reassign the results back to a again). Otherwise, I think you need to allocate a new array, so the other answers using filter are good.
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 19:01:41 UTC, Tofu Ninja wrote: Actually.. if I do dub describe on the root package it lists both the exe and the lib as targets but the build settings for the lib has "targetType": 6 which according to dub/source/dub/compilers/buildsettings.d is staticLibrary... is this a bug or what? omfg I should have read the build output more closely...right at the top "Dynamic libraries are not yet supported as dependencies - building as static library."... welp guess I give up then, 4 days waisted.
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 18:26:27 UTC, Tofu Ninja wrote: On Thursday, 26 January 2017 at 18:10:12 UTC, Tofu Ninja wrote: On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote: Is this not doable? I guess an alternative question, is there any way to have multiple binaries(an executable and a bunch of shared libs) built from a single dub package? Or should I just give up on trying to use dub for this... This [https://github.com/dlang/dub/issues/665] seems to be somewhat related to what I am trying to do, not sure if this got addressed at all though. Actually.. if I do dub describe on the root package it lists both the exe and the lib as targets but the build settings for the lib has "targetType": 6 which according to dub/source/dub/compilers/buildsettings.d is staticLibrary... is this a bug or what?
Re: Bug in documentation or misunderstanding it?
On Thursday, 26 January 2017 at 18:42:29 UTC, Suliman wrote: On Thursday, 26 January 2017 at 17:52:24 UTC, H. S. Teoh wrote: On Thu, Jan 26, 2017 at 05:38:59PM +, Suliman via Digitalmars-d-learn wrote: I read docs and can't understand what's wrong. Or I am do not understand it, or there is come mistake. Let's look at function https://dlang.org/phobos/std_stdio.html#.File.byLine auto byLine(Terminator = char, Char = char)(KeepTerminator keepTerminator = No.keepTerminator, Terminator terminator = '\x0a') what does mean first groups of scope: (Terminator = char, Char = char) ? Those are compile-time parameters. You specify them in a compile-time argument list using the !(...) construct, for example: auto lines = File("myfile.txt") .byLine!(dchar, char)(Yes.keepTerminator, '\u263a'); T So I am right about others items about for example that `=` is optional? Why this code is work: `file.byLine(KeepTerminator.no, 'm')`
Re: Bug in documentation or misunderstanding it?
On Thursday, 26 January 2017 at 17:52:24 UTC, H. S. Teoh wrote: On Thu, Jan 26, 2017 at 05:38:59PM +, Suliman via Digitalmars-d-learn wrote: I read docs and can't understand what's wrong. Or I am do not understand it, or there is come mistake. Let's look at function https://dlang.org/phobos/std_stdio.html#.File.byLine auto byLine(Terminator = char, Char = char)(KeepTerminator keepTerminator = No.keepTerminator, Terminator terminator = '\x0a') what does mean first groups of scope: (Terminator = char, Char = char) ? Those are compile-time parameters. You specify them in a compile-time argument list using the !(...) construct, for example: auto lines = File("myfile.txt") .byLine!(dchar, char)(Yes.keepTerminator, '\u263a'); T So I am right about others items about for example that `=` is optional?
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 18:10:12 UTC, Tofu Ninja wrote: On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote: Is this not doable? I guess an alternative question, is there any way to have multiple binaries(an executable and a bunch of shared libs) built from a single dub package? Or should I just give up on trying to use dub for this... This [https://github.com/dlang/dub/issues/665] seems to be somewhat related to what I am trying to do, not sure if this got addressed at all though.
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote: Is this not doable? I guess an alternative question, is there any way to have multiple binaries(an executable and a bunch of shared libs) built from a single dub package? Or should I just give up on trying to use dub for this...
Re: dub subpackage output to shared lib not working
On Sunday, 22 January 2017 at 08:16:49 UTC, Tofu Ninja wrote: Trying to get a dub sub package to output as a shared lib but for some reason I can only get it to output as a static lib. dub.json --- { "name": "tofueng", "targetType": "executable", "targetPath" : "game", "sourcePaths": ["eng"], "importPaths": ["eng"], "dependencies": { "tofueng:test": "*", }, "subPackages": [ { "name": "test", "targetType": "dynamicLibrary", "targetPath" : "game/libs", "sourcePaths": ["com/test"], "importPaths": ["com/test"] } ] } --- Get tofueng_test.lib instead of tofueng_test.dll. If I try to build the sub package directly it builds the dll. What am I doing wrong? Is this not doable?
Re: Bug in documentation or misunderstanding it?
On Thu, Jan 26, 2017 at 05:38:59PM +, Suliman via Digitalmars-d-learn wrote: > I read docs and can't understand what's wrong. Or I am do not understand it, > or there is come mistake. > > Let's look at function https://dlang.org/phobos/std_stdio.html#.File.byLine > > auto byLine(Terminator = char, Char = char)(KeepTerminator keepTerminator = > No.keepTerminator, Terminator terminator = '\x0a') > > what does mean first groups of scope: (Terminator = char, Char = char) ? Those are compile-time parameters. You specify them in a compile-time argument list using the !(...) construct, for example: auto lines = File("myfile.txt") .byLine!(dchar, char)(Yes.keepTerminator, '\u263a'); T -- If lightning were to ever strike an orchestra, it'd always hit the conductor first.
Re: Bug in documentation or misunderstanding it?
On Thursday, 26 January 2017 at 17:38:59 UTC, Suliman wrote: I read docs and can't understand what's wrong. Or I am do not understand it, or there is come mistake. [...] You have to import typecons.
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 11:44:27 UTC, Nicholas Wilson wrote: On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote: What is the D idiom for removing array elements that are present in another array? Is this the right/fastest way? int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto c = a.remove!(x => b.canFind(x)); assert(c == [1, 2, 5, 7]); filter. auto c = a.filter!(x => !b.canFind(x)).array; He wanted to remove elements. This will allocate a freaking new array. And do N function calls to build it. This is WORSE!
Bug in documentation or misunderstanding it?
I read docs and can't understand what's wrong. Or I am do not understand it, or there is come mistake. Let's look at function https://dlang.org/phobos/std_stdio.html#.File.byLine auto byLine(Terminator = char, Char = char)(KeepTerminator keepTerminator = No.keepTerminator, Terminator terminator = '\x0a') what does mean first groups of scope: (Terminator = char, Char = char) ? The second one as I understand it's options symbol `=` mean that there is some default values, so if I will call function I can do not set them, so predefined values will be used. Am I right? And If I do not want predefined I can pass my own like: `byLine(No.keepTerminator, 'SomeLetter')` for example: `file.byLine(No.keepTerminator, 'a')` But when I compile simple example I am getting compilation error: `undefined identifier 'No'` Where I am wrong?
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote: What is the D idiom for removing array elements that are present in another array? Is this the right/fastest way? int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto c = a.remove!(x => b.canFind(x)); assert(c == [1, 2, 5, 7]); import std.stdio, std.algorithm, std.range, std.array; int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto sortedB = sort(b.dup); auto c = a . filter!(i => !sortedB.contains(i)) . array ; assert(c == [1, 2, 5, 7]); If arrays get large, this should be more efficient since it performs O(n * n.log) instead of O(n * n). On the other hand you could also just use assumeSorted if b is already sorted, as in this case. But if you do, I still recommend adding an assert to check the range truly is sorted when debugging. It can be made to perform O(n) by sorting both a and b, but then you need to figure a way to return a back to normal order after filtering. I tried, and found it to be so hard I didn't bother.
Re: Trying to understand multidimensional arrays in D
On Thursday, 26 January 2017 at 05:20:07 UTC, Profile Anaysis wrote: (On the contrary, declarations in C or C++ looks rather unintuitive from this perspective: `T a[4][5][6]` is means that `a` is an array of 4 arrays of 5 arrays of 6 arrays of `T`. Note how we have to read left-to-right but then wrap around the string to get the meaning.) lol, I don' tknow what the last sentence means. wrap around the string? Do you mean look at the variable? For me the interpretation above is the most logical because it is a sequential operation in my mind, if you will. x of y of z and the chain can be cut off anywhere and the interpretation still be the same. This means that in `T a[4][5][6]`, the type `T[4][5][6]` is spread on both sides of the variable name `a`. In the interpretation, "`a` is an array of 4 arrays of 5 arrays of 6 arrays of `T`", note that 4, 5 and 6 are from the right side but T is from the left side. That's what I meant by wrap around.
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote: What is the D idiom for removing array elements that are present in another array? Is this the right/fastest way? int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto c = a.remove!(x => b.canFind(x)); assert(c == [1, 2, 5, 7]); filter. auto c = a.filter!(x => !b.canFind(x)).array;
Re: Trying to understand multidimensional arrays in D
On Thursday, January 26, 2017 05:44:04 Profile Anaysis via Digitalmars-d- learn wrote: > I am using static arrays because the size of the matrix is fixed. > I need to allocate them though because that is what my > matrix_history contains. If I understood correctly, you want a dynamic array of static arrays where the static array is therefore an entry in your "matrix history." That does not require that you allocate a static array. It just requires that you allocate the dynamic array of static arrays. For instance, if you had an integer instead of a matrix, you would have something like int[] arr; and when you appended to it, you would just append the value. e.g. arr ~= 42; arr ~= 77; arr ~= 9; No allocation of the values is required. The dynamic array may very well do some reallocating to fit the new values (depending on its current capacity), but the values themselves are not allocated. So, if you have a dynamic array of static arrays int[4][4][] arr; then you just append each static array. e.g. int[4][4] value; // fill in value... arr ~= value; or arr ~= [[9, 9, 9, 9], [7, 7, 7, 7], [2, 2, 2, 2], [3, 3, 3, 3]]; Again. You're not allocating the values that you're appending at all. At most, the dynamic array ends up being reallocated to make room for more elements. - Jonathan M Davis
Re: Trying to understand multidimensional arrays in D
Sorry. I mistyped some of my examples. Obviously dropped some news: auto a = new int[](4); auto b = new int[][](4); And the static arrays should be: int[4] c; int[][4] d; And I would also like managed to overlook there is no static array in sight here: auto y = new int[1][2][][](3,4); The 1 and 2 are not creating static arrays. They are dynamic arrays. The following are exactly the same: auto a1 = new int[](2); auto a2 = new int[2]; The syntax in a2 is the original syntax for allocating space for dynamic arrays. The () was added later. The point I made about changing the declaration of x remains.
Re: Trying to understand multidimensional arrays in D
On Thursday, 26 January 2017 at 05:50:03 UTC, Profile Anaysis wrote: It is inconsistent with dynamic arrays and mixing them creates a mess in the order of indices. I best someone was asleep at the wheel when programming the code for static arrays. (probably someone different than who programmed the dynamic arrays) This is a bug IMO.(unfortunately one that can't be fixed ;/) No, there's no inconsistence and there's no bug. Shorten things down a bit: ``` auto x = new int[][](3,4); auto y = new int[3][](4); writefln("%s, %s", x[0].length, y[0].length); ``` This will print 4, 3. Why? auto a = int[](4); In this case, a is an array of int. The allocation makes space for 4 values of type int. auto b = int[][](4); Here, b is an array of int[]. The allocation makes space for values of type int[]. The following are the equivalent declarations for static arrays: auto c = int[4]; auto d = int[][4]; In other words int[][4] is the static equivalent of new int[][](4). Following from that: auto e = new int[][](4, 3); This creates an array of 4 values of type int[], each of which is an array that holds 3 values of type int. The static equivalent: auto f = int[3][4]; So based on that, you should be able to see that the problem is not in the implementation of static arrays in D, but a mismatch in your declarations. auto x = new int[][][][](1,2,3,4); auto y = new int[1][2][][](3,4); // Does not match declaration of x To get what you want, change the declaration of x: auto x = new int[][][][](4, 3, 2, 1);
Re: Min, max of enum
On Thursday, 26 January 2017 at 05:58:26 UTC, Profile Anaysis wrote: Since we do not have attributes for enums, I use _ in front of the names for meta values. I need to get the non-meta values for the enum so I can iterate over it and use it properly. enum myEnum { _Meta1 = 0, A,B,C, _Meta3 = 43, D = 3, } The num, for all practical purposes does not contain _Meta1, and_Meta3. But in code I use to!myEnum(intI) and having the meta values complicate things(simple shifting may or may not work). I also need to create array indexers based on myEnum that don't include the meta characters. What I do a lot is convert integers in to fields of the enum. If I do not include any Meta, then it is straight forward to!myEnum(i), but with them it is not, so doing things like int[myEnum] x; x[to!myEnum(i))] is difficult because the conversion will be invalid for meta. I'd have to do some work on i to get the 0-n representation to map properly in to the enum... basically avoiding the meta fields. This would all be solved with attributes for enums, but that, I suppose is a pipe dream. Any ideas how I can make this easy? Like Stefan said, __traits(allMembers, myEnum) lets you iterate over the elements of the enum. For a to!myEnum that ignores _Meta fields, you could do something like this: T toEnum(T)(int n) { foreach (element; __traits(allMembers, myEnum)) { static if (element[0] != '_') { if (n == cast(int)__traits(getMember, myEnum, element)) return __traits(getMember, myEnum, element); } } assert(false); } Looking at your code though, I wonder if the problem you want solved is a different one. Especially this part: I'd have to do some work on i to get the 0-n representation to map properly in to the enum... basically avoiding the meta fields. If I understand you correctly, you want this: enum myEnum { _Meta1 = 0, A,B,C, _Meta3 = 43, D = 3, } to become this: enum myEnum { A = 0, B = 1, C = 2, D = 3 } That's a taller order, especially given that the original is equivalent to this: enum myEnum { A = 1, B = 2, C = 3, D = 3 // And some meta members, but not relevant here. } One option would look somewhat like this: alias myEnum = Enum!q{ _Meta1 = 0, A, B, C, _Meta2 = 43, D }; template Enum(string enumBody) { mixin(generateEnum!enumBody); } string generateEnum(string enumBody)() { import std.conv; string result; mixin("enum members {"~enumBody~"}"); foreach (element; __traits(allMembers, members)) { if (element[0] != '_') { result ~= element ~ ","; } } return "@MetaData!\""~enumBody~"\" enum Enum {"~result~"}"; } template MetaData(string enumBody) { mixin(generateMeta!enumBody); } string generateMeta(string enumBody)() { import std.conv; string result; mixin("enum members {"~enumBody~"}"); foreach (element; __traits(allMembers, members)) { if (element[0] == '_') { result ~= element ~ " = " ~ (cast(int)__traits(getMember, members, element)).to!string ~ ","; } } return "enum MetaData {"~result~"}"; } template meta(T) if (is(T == enum)) { import std.typetuple; alias meta = AliasSeq!(__traits(getAttributes, T))[0]; } void main() { import std.stdio; import std.conv; import std.typetuple; writeln(myEnum.A, ": ", cast(int)myEnum.A); writeln(myEnum.B, ": ", cast(int)myEnum.B); writeln(myEnum.C, ": ", cast(int)myEnum.C); writeln(myEnum.D, ": ", cast(int)myEnum.D); writeln(meta!myEnum._Meta1, ":", cast(int)meta!myEnum._Meta1); writeln(meta!myEnum._Meta2, ":", cast(int)meta!myEnum._Meta2); } This lets you define the enum with a somewhat familiar syntax: alias myEnum = Enum!q{ _Meta1 = 0, A, B, C, _Meta2 = 43, D }; and generates from that the equivalent of this: @myEnum_Meta enum myEnum { A, B, C, D } enum myEnum_Meta { _Meta1 = 0, _Meta2 = 43 }
D idom for removing array elements
What is the D idiom for removing array elements that are present in another array? Is this the right/fastest way? int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto c = a.remove!(x => b.canFind(x)); assert(c == [1, 2, 5, 7]);
Re: Why is &array[0] @safer than array.ptr?
On Wednesday, 25 January 2017 at 22:59:55 UTC, Jonathan M Davis wrote: So, yes, if all you're planning to do is look at the pointer to the first element in the array, then &arr[0] is safer, but odds are quite low that that's actually what you're going to do, and in all of the other cases, you might as well just use .ptr. So, telling folks to go use &arr[0] instead of .ptr doesn't seem very helpful to me. Pehaps it should say something like: arr.ptr is deprecated in @safe code. Use &arr[0] for checked access or remove the @safe attribute. That would make it clear that .ptr is not an issue, only .ptr in @safe.