Re: Function template argument deduction
On Saturday, 7 April 2018 at 05:10:05 UTC, Paul Backus wrote: I'm playing around with functional programming in D, and have run into a problem with the following code: [...] I don't see the error you are talking about: https://run.dlang.io/is/XWPIc1 Are you using the latest compiler?
Function template argument deduction
I'm playing around with functional programming in D, and have run into a problem with the following code: --- list.d import std.variant: Algebraic, This, visit; import std.typecons: Tuple, tuple; struct Nil {} alias List(T) = Algebraic!( Nil, Tuple!(T, "head", This*, "tail") ); alias Cons(T) = Tuple!(T, "head", List!T*, "tail"); List!T* list(T)(T[] items...) { if (items.length == 0) return new List!T(Nil()); else return new List!T(Cons!T(items[0], list(items[1..$]))); } string list2string(T)(List!T list) { import std.stdio: write; list.visit!( (Nil _) => "nil", (Cons!T cons) => "cons(" ~ cons.head ~ ", " ~ list2string(*cons.tail) ~ ")" ); } unittest { List!int* myList = list(1, 2, 3); assert(list2string(*myList) == "cons(1, cons(2, cons(3, nil)))"); } --- The error I get is "template list.list2string cannot deduce function from argument types [...]"; i.e., the compiler can't figure out that T is supposed to be 'int'. My question is, why not? Is there anything I can do to get this to work? The compiler seems to be able to handle this sort of thing in general (e.g., it can deduce 'int' from an argument of type 'Tuple!(int, int)'), so what makes this particular case fail?
Re: How to destruct class instances allocated by a Region-allocator over a single GC block
On Tuesday, 3 April 2018 at 09:14:28 UTC, Eduard Staniloiu wrote: So, say `reg` is your allocator, your workflow would be auto obj = reg.make!Type(args); /* do stuff */ reg.dispose(obj); // If Type has a __dtor, it will call obj.__dtor // and then reg.deallocate(obj) If I do sucessive calls to reg.make!X where X are different kinds of classes of different sizes how does reg.dispose(obj) figure out at which address(es) (where emplace filled in the data) the objects reside?
Re: Making emplaceRef public
On Friday, 6 April 2018 at 17:46:26 UTC, Per Nordlöw wrote: Why isn't `std.conv.emplaceRef` public when `std.conv.emplace` is? AFAICT, emplaceRef(x, ...) is a bit more @safe than emplace(, ...) ... I had the same thoughts too: https://issues.dlang.org/show_bug.cgi?id=18701 We can even do this without introducing a new symbol, but simply let emplace accept pointers and ref like we need with formattedRead for nice backwards compatibility.
Making emplaceRef public
Why isn't `std.conv.emplaceRef` public when `std.conv.emplace` is? AFAICT, emplaceRef(x, ...) is a bit more @safe than emplace(, ...) ...
Re: Proper way to fix core.exception.UnicodeException@src\rt\util\utf.d(292): invalid UTF-8 sequence by File.readln()
On Friday, April 06, 2018 16:10:56 Dr.No via Digitalmars-d-learn wrote: > I'm reading line by line the lines from a CSV file provided by > the user which is assumed to be UTF8. But an user has provided an > > ANSI file which resulted in the error: > >core.exception.UnicodeException@src\rt\util\utf.d(292): invalid > >UTF-8 sequence > > (it happend when the user took the originally UTF8 encoded file > generated by another application, made some edit using an editor > (which I don't know the name) then saved not aware it was > changing the encoding to ANSI. > > My question is: what's the proper way to solve that? using toUTF8 > > didn't solve: > > while((line = csvFile.readln().toUTF8) !is null) { > > I didn't find a way to set explicitly the encoding with > std.stdio.File to set to UTF8 regardless it's an ANSI or already > UTF8. > I don't want to conver the whole file to UTF8, the CSV file can > be large and might take quite while. And if I do so to a > temporary copy the file (which will make things even more slow) > to avoid touch user's original file. > > I thought in writing my own readLine() with > std.stdio.File.byChunk to take as many bytes as possible until > '\n' byte is seen, treat it as UTF8 and return. > > But I'd like to not reinvent the wheel and use something native, > if possible. Any ideas? In general, Phobos pretty much requires that text files be in UTF-8 or that they be in UTF-16 or UTF-32 with the native endianness. Certainly, char, wchar, and dchar are assumed by both the language and the library to be valid UTF-8, UTF-16, and UTF-32 respectively, and if you do anything with a string as a range, by default, it will decode the code units to code points, meaning that it will validate the UTF. If you want to read in anything that is not going to be valid UTF, then you're going to have to read it in as ubytes rather than as characters. If you're dealing with text that is supposed to be valid UTF but might contain invalid characters, then you can use std.utf.byCodeUnit to treat a string as a range of code units where it replaces invalid UTF with the Unicode replacement character, but you'd still have to read in the text as bytes (e.g. readText validates that the text is proper UTF). std.utf.byUTF could be use instead of byCodeUnit to convert to UTF-8, UTF-16, or UTF-32, and invalid UTF will be replaced with the replacement character (so it doesn't have to be the target encoding, but it does have to be one of those three encodings and not something else). byUTF8 is basically the version of byUTF!char / byChar that returns a string rather than a lazy range, which is why it would have not worked for you if the file is not UTF-8, UTF-16, or UTF-32. If you're dealing with an encoding other than UTF-8, UTF-16, or UTF-32, and you've read the data in as ubytes, then std.encoding _might_ help, but it's not a great module and doesn't support a lot of encodings. On the other hand, if by ANSI, you mean the encoding that Windows uses with the A versions of its functions, then you can use std.windows.charset.fromMBSz to convert it to string, though it will need to be a null terminated immutable(char)* to work with fromMBSz, so somewhat stupidly, it basically needs to be a null-terminated string that isn't valid UTF-8 that you pass using str.ptr or [0]. If the encoding you're dealing with is not one that works with fromMBSz, and it is not one of the few supported by std.encoding, then you're on your own. - Jonathan M Davis
Proper way to fix core.exception.UnicodeException@src\rt\util\utf.d(292): invalid UTF-8 sequence by File.readln()
I'm reading line by line the lines from a CSV file provided by the user which is assumed to be UTF8. But an user has provided an ANSI file which resulted in the error: core.exception.UnicodeException@src\rt\util\utf.d(292): invalid UTF-8 sequence (it happend when the user took the originally UTF8 encoded file generated by another application, made some edit using an editor (which I don't know the name) then saved not aware it was changing the encoding to ANSI. My question is: what's the proper way to solve that? using toUTF8 didn't solve: while((line = csvFile.readln().toUTF8) !is null) { I didn't find a way to set explicitly the encoding with std.stdio.File to set to UTF8 regardless it's an ANSI or already UTF8. I don't want to conver the whole file to UTF8, the CSV file can be large and might take quite while. And if I do so to a temporary copy the file (which will make things even more slow) to avoid touch user's original file. I thought in writing my own readLine() with std.stdio.File.byChunk to take as many bytes as possible until '\n' byte is seen, treat it as UTF8 and return. But I'd like to not reinvent the wheel and use something native, if possible. Any ideas?
Re: dustmite watch shell script (.test vs .lookahead.*)
On Friday, 6 April 2018 at 15:35:59 UTC, Anonymouse wrote: The dustmite wiki[0] lists the following example script for use to monitor the reduction progress: Here's a more complete version that also works with -j: https://gist.github.com/CyberShadow/2e8f01895c248111c171e982313bb008
dustmite watch shell script (.test vs .lookahead.*)
The dustmite wiki[0] lists the following example script for use to monitor the reduction progress: #!/bin/sh watch -cn 0.1 "zsh -c 'ls -al $1.reduced/**/*.d ; colordiff -ru $1.reduced $1.test'" This repeatedly compares the $1.reduced directory with a $1.test directory. The dustmite run however doesn't seem to produce a (stable) $1.test, only several $1.lookahead.* directories. drwxr-xr-x 1 zorael zorael 362 apr 6 17:21 . drwxr-xr-x 1 zorael zorael 24 apr 6 17:21 source.lookahead.7170 drwxr-xr-x 1 zorael zorael 24 apr 6 17:21 source.lookahead.7169 drwxr-xr-x 1 zorael zorael 24 apr 6 17:21 source -rwxr-xr-x 1 zorael zorael 186 apr 6 10:23 tester The command used was `dustmite -j2 --strip-comments source /abs/path/to/tester`. I'm limiting the number of jobs to 2 so as not to run out of memory. dmd is a bit unreasonable. Why is there no .test directory? Changing the script to $1.lookahead.* doesn't work as it passes (jobs+1) arguments to colordiff, which only accepts 2. Is there any way to glob only one .lookahead.* directory? Some other solution? [0]: https://github.com/CyberShadow/DustMite/wiki
Re: c2 classes
On Friday, 6 April 2018 at 14:43:25 UTC, Ali wrote: On Friday, 6 April 2018 at 14:31:49 UTC, Alex wrote: On Friday, 6 April 2018 at 13:41:50 UTC, aerto wrote: [...] A question from me, since I am also still learning D what is the difference between those following two declarations UUsers[int] uid; UUsers[] uid; T[U] declares an Associative Array but T[] declares a Dynamic Array. Some examples will help: --- void main() { char[int] s1; char[] s2; s1[1] = 'c'; //allowed, it is an Associative array. key 1 stores value 'c' s2[0] = 1; //error: out of bounds of array s2 } --- You can check out the spec[0] and the tour[1] [0]: https://dlang.org/spec/hash-map.html [1]: https://tour.dlang.org/tour/en/basics/associative-arrays
Re: c2 classes
On Friday, 6 April 2018 at 14:31:49 UTC, Alex wrote: On Friday, 6 April 2018 at 13:41:50 UTC, aerto wrote: its possible to make this work ?? import std.stdio; class UUsers { public: int age; } class users { public: int[int] uid; } void main() { users newuser = new users(); newuser.uid[0].age = 23; writeln(newuser.uid[0].age); } It depends on what you want to achieve... This is runnable: ``` import std.stdio; class UUsers { this(int val) { age = val; } public: int age; } class users { public: UUsers[int] uid; } void main() { users newuser = new users(); newuser.uid[0] = new UUsers(23); writeln(newuser.uid[0].age); } ``` A question from me, since I am also still learning D what is the difference between those following two declarations UUsers[int] uid; UUsers[] uid;
Re: c2 classes
On Friday, 6 April 2018 at 13:41:50 UTC, aerto wrote: its possible to make this work ?? import std.stdio; class UUsers { public: int age; } class users { public: int[int] uid; } void main() { users newuser = new users(); newuser.uid[0].age = 23; writeln(newuser.uid[0].age); } This will work import std.stdio; class UUsers { public: int age; } class users { public: UUsers[] uid; } void main() { users userList = new users(); userList.uid ~= new UUsers(); userList.uid[0].age = 24 ; writeln(userList.uid[0].age); } Let me try to explain why Basically, what you wanted to do is have two classes one will hold user's information, and another holding a user list For the second class to hold user list this line int[int] uid; became this line UUsers[] uid; In you code, there was no relation between the two classes Then in your main You instantiate your users list object users userList = new users(); Then you instantiate a user object and append it to the list (~= is the append operator) userList.uid ~= new UUsers(); Finally you assign a value to your user object age and print it userList.uid[0].age = 24 ; writeln(userList.uid[0].age);
Re: c2 classes
On Friday, 6 April 2018 at 13:41:50 UTC, aerto wrote: its possible to make this work ?? import std.stdio; class UUsers { public: int age; } class users { public: int[int] uid; } void main() { users newuser = new users(); newuser.uid[0].age = 23; writeln(newuser.uid[0].age); } It depends on what you want to achieve... This is runnable: ``` import std.stdio; class UUsers { this(int val) { age = val; } public: int age; } class users { public: UUsers[int] uid; } void main() { users newuser = new users(); newuser.uid[0] = new UUsers(23); writeln(newuser.uid[0].age); } ```
Re: Compile-time variables
On Friday, 6 April 2018 at 14:15:08 UTC, Kayomn wrote: On Friday, 6 April 2018 at 13:55:55 UTC, nkm1 wrote: [...] Figured I had a handle on how it worked doing but guess not. One final question, however. [...] Nevermind, I'm blind. I missed the post-increment in newID().
Re: Compile-time variables
On Friday, 6 April 2018 at 13:55:55 UTC, nkm1 wrote: On Friday, 6 April 2018 at 13:10:23 UTC, Kayomn wrote: ID tags are unique and spsecific to the class type. There shouldn't be more than one type ID assigned to one class type. The idea behind what it is I am doing is I am implementing a solution to getting a type index, similar to std.variant.Variant.type(). The way that I implemented this in C++ is like so: inline unsigned int getNodeTypeID() { static unsigned int lastID = 0; return lastID++; } template inline unsigned int getNodeTypeID() { static unsigned int typeID = getNodeTypeID(); return typeID; } In this C++ example I am exploiting the fact that templates are generated at compile-time to execute getNodeTypeID for each new type instance generated. After initial type generation, whenever they are called at runtime they were return the ID assigned to that function template instance that was generated at compile-time. It's pretty simple, and to be honest I'm surprised this has been causing me such a headache implementing it in D. That's because the C++ code doesn't do what you think it does. Apparently you think that getNodeID() is executed at compile time. This is not the case, which you can verify by adding "constexpr" to it: $ g++ -std=c++14 -Wall -Wextra -c -o example example.cpp main.cpp: In function ‘constexpr unsigned int getNodeTypeID()’: main.cpp:2:25: error: ‘lastID’ declared ‘static’ in ‘constexpr’ function static unsigned int lastID = 0; In fact, you're "exploiting" the fact that static variables in C++ can be initialized at runtime (which is probably not what you want). The equivalent D code is: uint newID() { static uint lastID; return lastID++; } uint getNodeID(T)() { static bool inited; static uint id; if (!inited) { id = newID(); inited = true; } return id; } (yes, C++ does insert some hidden bool that tells it whether the variable was initialized or not). Naturally, you can't use that for constructing switches or other compile time constructs. Figured I had a handle on how it worked doing but guess not. One final question, however. I've implemented this test bed with your example to what I think is your exact implementation, but it seems to be giving unexpected output. import std.stdio; uint newID() { static uint lastID; return lastID; } uint getNodeID(T)() { static bool inited; static uint id; if (!inited) { id = newID(); inited = true; } return id; } class Node {} class Sprite {} class Camera {} void main() { // Test 01. writeln("Test 01."); writeln(getNodeID!(Node)(),'\t',getNodeID!(Sprite)(),'\t',getNodeID!(Camera)()); // Test 02. writeln("Test 02."); writeln(getNodeID!(Node)(),'\t',getNodeID!(Sprite)(),'\t',getNodeID!(Camera)()); } Output: Performing "debug" build using gdc for x86_64. dlangtest ~master: building configuration "application"... Running ./dlangtest Test 01. 0 0 0 Test 02. 0 0 0 Have I misunderstood something?
Re: Compile-time variables
On Friday, 6 April 2018 at 13:10:23 UTC, Kayomn wrote: ID tags are unique and spsecific to the class type. There shouldn't be more than one type ID assigned to one class type. The idea behind what it is I am doing is I am implementing a solution to getting a type index, similar to std.variant.Variant.type(). The way that I implemented this in C++ is like so: inline unsigned int getNodeTypeID() { static unsigned int lastID = 0; return lastID++; } template inline unsigned int getNodeTypeID() { static unsigned int typeID = getNodeTypeID(); return typeID; } In this C++ example I am exploiting the fact that templates are generated at compile-time to execute getNodeTypeID for each new type instance generated. After initial type generation, whenever they are called at runtime they were return the ID assigned to that function template instance that was generated at compile-time. It's pretty simple, and to be honest I'm surprised this has been causing me such a headache implementing it in D. That's because the C++ code doesn't do what you think it does. Apparently you think that getNodeID() is executed at compile time. This is not the case, which you can verify by adding "constexpr" to it: $ g++ -std=c++14 -Wall -Wextra -c -o example example.cpp main.cpp: In function ‘constexpr unsigned int getNodeTypeID()’: main.cpp:2:25: error: ‘lastID’ declared ‘static’ in ‘constexpr’ function static unsigned int lastID = 0; In fact, you're "exploiting" the fact that static variables in C++ can be initialized at runtime (which is probably not what you want). The equivalent D code is: uint newID() { static uint lastID; return lastID++; } uint getNodeID(T)() { static bool inited; static uint id; if (!inited) { id = newID(); inited = true; } return id; } (yes, C++ does insert some hidden bool that tells it whether the variable was initialized or not). Naturally, you can't use that for constructing switches or other compile time constructs.
c2 classes
its possible to make this work ?? import std.stdio; class UUsers { public: int age; } class users { public: int[int] uid; } void main() { users newuser = new users(); newuser.uid[0].age = 23; writeln(newuser.uid[0].age); }
Re: Compile-time variables
Besides this, I tried something with types used as user defined attributes. https://dlang.org/spec/attribute.html#uda Automatic compile time tagging is not my speciality, however, I think is also achievable with mixins somehow? But I don't know how to workaround the bug https://issues.dlang.org/show_bug.cgi?id=18718 at this moment... https://run.dlang.io/is/DmBhO5 Does the default case handle an unspecified class or does it handle a class which is specified, but is not mentioned in any of previous cases? So in this example code the switch table is being used for loading data serialized into text. If the class cannot determine the node ID or it uses the default node type ID (e.g. the Node type if super "Node") it will create a simple node, as you can always be sure no matter what the type there will be sufficient information stored in the data to construct a default Node. Another information shortage is: are the tags exclusive or not? So, is it possible that a class has more then one tag (still being unique (tuple))? ID tags are unique and spsecific to the class type. There shouldn't be more than one type ID assigned to one class type. The idea behind what it is I am doing is I am implementing a solution to getting a type index, similar to std.variant.Variant.type(). The way that I implemented this in C++ is like so: inline unsigned int getNodeTypeID() { static unsigned int lastID = 0; return lastID++; } template inline unsigned int getNodeTypeID() { static unsigned int typeID = getNodeTypeID(); return typeID; } In this C++ example I am exploiting the fact that templates are generated at compile-time to execute getNodeTypeID for each new type instance generated. After initial type generation, whenever they are called at runtime they were return the ID assigned to that function template instance that was generated at compile-time. It's pretty simple, and to be honest I'm surprised this has been causing me such a headache implementing it in D.
Re: Compile-time variables
On Friday, 6 April 2018 at 02:20:29 UTC, Kayomn wrote: Wrong example code, here's the correct example: switch (queryString(childJson,"type")) { case (typeof (Sprite).name): child = this.addChild!(Sprite)(childName); break; case (typeof (Camera).name): child = this.addChild!(Camera)(childName); break; default: child = this.addChild!(Node)(childName); break; } Hi, could you show a bit more implementation details in the C++ version that works? Maybe someone can translate that to the appropriate D version? The problem seems to be that switching on a runtime value and pattern matching with a compile time value is hard to pull off automatically without some sort of bridge (or of course I've misunderstood this exercise) So if you had: class R { string type() { return R.stringof; } } class A: R { override string type() { return A.stringof; } } class B: R { override string type() { return B.stringof; } } string type(T: R)() { return T.stringof; } void main() { R node = new A; final switch (node.type) { case type!R: writeln("R"); break; case type!A: writeln("A"); break; case type!B: writeln("B"); break; } } (maybe not a good idea to use stringof though, typeid probably better) Cheers
Re: Compile-time variables
On Friday, 6 April 2018 at 02:20:29 UTC, Kayomn wrote: Wrong example code, here's the correct example: switch (queryString(childJson,"type")) { case (typeof (Sprite).name): child = this.addChild!(Sprite)(childName); break; case (typeof (Camera).name): child = this.addChild!(Camera)(childName); break; default: child = this.addChild!(Node)(childName); break; } Ok, first of all, I'm not sure about the question, because of the following: Does the default case handle an unspecified class or does it handle a class which is specified, but is not mentioned in any of previous cases? Or does the default case handle both of these circumstances? Without a master list this play an important role, I think. Another information shortage is: are the tags exclusive or not? So, is it possible that a class has more then one tag (still being unique (tuple))? Besides this, I tried something with types used as user defined attributes. https://dlang.org/spec/attribute.html#uda Automatic compile time tagging is not my speciality, however, I think is also achievable with mixins somehow? But I don't know how to workaround the bug https://issues.dlang.org/show_bug.cgi?id=18718 at this moment... https://run.dlang.io/is/DmBhO5