Re: Cannot call @system funciton (stdout)
On Sunday, 16 August 2020 at 18:13:07 UTC, Anonymouse wrote: Just as a drive-by comment, the main stdio thing I came across that I couldn't do from within @safe was stdout.flush(), which I need to call manually for Cygwin terminals and some terminals embedded in editors (vscode). If someone knows why, please tell me. Cygwin terminals are not recognized as terminals, you should set line buffered mode, then it will flush every line.
Re: Subtyping with alias this
On Tuesday, 18 August 2020 at 05:54:16 UTC, H. S. Teoh wrote: Here's a working example: Thank you, it works!
Re: Subtyping with alias this
On Tue, Aug 18, 2020 at 05:34:58AM +, novice3 via Digitalmars-d-learn wrote: [...] > The problem is: > if i use fmt.spec in overloaded toString(), > when i get error "phobos/std/format.d(2243): Error: no property ip for > type onlineapp.IpV4Address" Here's a working example: - import std; struct IpV4Address { private uint ip; alias ip this; void toString(W,Char)(W sink, FormatSpec!Char fmt) { if (fmt.spec == 's') { // Deal with %s here sink.formattedWrite("%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); } else { // Everything else formatValue(sink, this.ip, fmt); } } // This unittest is to workaround the sillyness that if toString // doesn't compile, std.format pretends it doesn't exist and/or // the compiler swallows the real error and substitutes it with // an irrelevant error that has nothing to do with the real // problem. unittest { IpV4Address ip; auto app = appender!string; ip.toString(app, FormatSpec!char.init); } } unittest { auto ip = IpV4Address(0x01020304); writefln("%s", ip); writefln("%x", ip); writefln("%d", ip); } - T -- No! I'm not in denial!
Re: Subtyping with alias this
On Monday, 17 August 2020 at 14:43:27 UTC, H. S. Teoh wrote: What you need is to create an overload of toString that takes a FormatSpec parameter, so that you can decide what should be output for which format spec. Something along these lines: Sorry, i can't make it works. I tried ti read format.d, but it too complex for me. The problem is: if i use fmt.spec in overloaded toString(), when i get error "phobos/std/format.d(2243): Error: no property ip for type onlineapp.IpV4Address" reduced code https://run.dlang.io/is/Kgbhfd ``` import std.format; struct IpV4Address { private uint ip; alias ip this; void toString(W,Char)(W sink, FormatSpec!Char fmt) { sink(fmt.spec); // ERROR //sink("s"); // OK } } void main() { IpV4Address x; assert( format("%s", x) == "s"); } ``` /dlang/dmd-nightly/linux/bin64/../../src/phobos/std/format.d(2243): Error: no property ip for type onlineapp.IpV4Address /dlang/dmd-nightly/linux/bin64/../../src/phobos/std/format.d(1875): Error: template instance std.format.formatValueImpl!(Appender!string, IpV4Address, char) error instantiating /dlang/dmd-nightly/linux/bin64/../../src/phobos/std/format.d(576): instantiated from here: formatValue!(Appender!string, IpV4Address, char) /dlang/dmd-nightly/linux/bin64/../../src/phobos/std/format.d(6630): instantiated from here: formattedWrite!(Appender!string, char, IpV4Address) onlineapp.d(17):instantiated from here: format!(char, IpV4Address)
Re: How to sort a multidimensional ndslice?
The following code just sorts each row: -- /+dub.sdl: dependency "mir-algorithm" version="~>3.9.24" +/ import mir.ndslice; import mir.ndslice.sorting; import mir.algorithm.iteration: each; void main() { // fuse, not sliced if you use an array of arrays for argument auto a = [[1, -1, 3, 2], [0, -2, 3, 1]].fuse; // make an index a.byDim!0.each!(sort!larger); import std.stdio; writeln(a); // [[3, 2, 1, -1], [3, 1, 0, -2]] } auto larger(C)(C u, C v) { return u > v; } -- To reorder the columns data according to precomputed index: -- /+dub.sdl: dependency "mir-algorithm" version="~>3.9.24" +/ import mir.ndslice; import mir.series; import mir.ndslice.sorting; import mir.algorithm.iteration: each; import mir.math.sum; void main() { // fuse, not sliced if you use an array of arrays for argument auto a = [[1, -1, 3, 2], [0, -2, 3, 1]].fuse; // make an index auto index = a.byDim!1.map!sum.slice; auto s = index.series(a.transposed); auto indexBuffer = uninitSlice!int(s.length); auto dataBuffer = uninitSlice!int(s.length); sort!larger(s, indexBuffer, dataBuffer); import std.stdio; writeln(a); /// [[3, 2, 1, -1], [3, 1, 0, -2]] } auto larger(C)(C u, C v) { return u > v; } -
How to sort a multidimensional ndslice?
I want to sort a two-dimensional ndslice by its columns according to some predefined predicate. What I mean is _not_ sorting the contents of each column individually, but instead to reorder the entire columns of the matrix so that they are sorted according to some "greater than" function. Here's a MWE (the `larger` function is just an example): ``` import std.stdio; import mir.ndslice.slice; import mir.ndslice.sorting; void main() { auto a = [[1, -1, 3, 2], [0, -2, 3, 1]].sliced; writeln(a); a.byDim!1.sort!((u, v) => larger(u, v)); writeln(a); } auto larger(C)(C u, C v) { import mir.math.sum : sum; return sum(u) > sum(v); } ``` I would have expected this to print: [[1, -1, 3, 2], [0, -2, 3, 1]] [[3, 2, 1, -1], [3, 1, 0, -2]] but instead it prints [[1, -1, 3, 2], [0, -2, 3, 1]] [[1, -1, 3, 2], [0, -2, 3, 1]] i.e, nothing happens! Any suggestions? Arredondo.
Re: Can a call to pragma(msg, __FILE__, ...) be mixin templatized?
On Monday, 17 August 2020 at 21:18:41 UTC, Per Nordlöw wrote: I'm using pragma(msg, __FILE__, "(", __LINE__, ",1): Debug: ", "A useful debug message"); to print compile-time information formatted as standard compiler diagnostics. These are picked up by Emacs Flycheck and overlayed in the editor and listen in the *Flycheck errors* buffer. Very convenient. When I want to get the type of something at compile-time. In order to not having to repeat oneself I'm now looking for a way to extract this into a `mixin template`. Is this possible somehow and still preserve the instantiation site values of `__FILE__` and `__LINE__`? mixin template ctLog(string msg, string file = __FILE__, size_t line = __LINE__) { pragma(msg, file, "(", line, "): ", msg); } mixin ctLog!"Module scope"; unittest { mixin ctLog!"function scope"; } struct S { mixin ctLog!"Struct scope"; } This works for me. -- Simen
Can a call to pragma(msg, __FILE__, ...) be mixin templatized?
I'm using pragma(msg, __FILE__, "(", __LINE__, ",1): Debug: ", "A useful debug message"); to print compile-time information formatted as standard compiler diagnostics. These are picked up by Emacs Flycheck and overlayed in the editor and listen in the *Flycheck errors* buffer. Very convenient. When I want to get the type of something at compile-time. In order to not having to repeat oneself I'm now looking for a way to extract this into a `mixin template`. Is this possible somehow and still preserve the instantiation site values of `__FILE__` and `__LINE__`?
Re: vibe.d and my first web service
On Thursday, 13 August 2020 at 09:54:06 UTC, Mr. Backup wrote: On Wednesday, 12 August 2020 at 13:46:06 UTC, James Blachly wrote: Unfortunately the problem still occurs with Vibe.d 0.9.0 IMO **this is the single most important problem to fix** for vibe.d -- if the most basic of examples (indeed, supplied by dub itself) fails so spectacularly, the casual new user will not spend the time to find out why this is happening, but instead move on. The ctrl-C non-termination bug has existed since at least 2015 from what I can tell from the forums. As a casual new novice, I really like dlang as such, and I think it should be the most widespread and popular language in the world. And as soon as I came across it, I wanted to use it in my project. But it has many packages for the same things, but these packages are unfinished. Everyone creates their own. You start comparing them and don't know what to choose for your job and then you find out that you should have chosen another and then find out that you should have written it yourself. And then I finally done it in golang in a while. I think the dlang community should focus on creating a quality standard library. We live in the 21st century where there are web technologies everywhere around us, so I think that the http package should be part of a standard library. It takes time. I was comparing packages available in D compared to say nodejs which I've been using for a while. Very few important ones are missing. The others too lack some documentation. Other than that, you get pretty much what you need. Except cloud sdks. also using vibe.d has some missing pieces on how to do certain things... that I agree we Users need to do writing about them. You're also right that people keep rolling their own implementations. Most people here are really good and can roll their own so its quite tempting...plus reading someone's code and implementation can be a lil...sometimes. except rolling your own means it'll be half baked and undocumented. Also I suspect lot of community members primary don't do web stuff primarily. If you ask me, I'll say vibe.d is the most solid and feature complete web framework at the moment...code, docs, libraries. It's not perfect but its never been a blocker. That's if you know your way around it. Sonke is a pretty cool guy. Will be nice if he had a GitHub sponsor or something for vibe.d Hunt framework is also your laravel D alternative.
Re: Subtyping with alias this
On Mon, Aug 17, 2020 at 02:29:47PM +, novice3 via Digitalmars-d-learn wrote: [...] > ``` > struct IpV4Address > { > private uint ip; > alias ip this; > > string toString() > { > import std.conv: to; > return to!string((ip >>> 24) & 0xFF) ~ "." ~ >to!string((ip >>> 16) & 0xFF) ~ "." ~ >to!string((ip >>> 8) & 0xFF) ~ "." ~ >to!string(ip & 0xFF); > } What you need is to create an overload of toString that takes a FormatSpec parameter, so that you can decide what should be output for which format spec. Something along these lines: string toString(W,Char)(W sink, FormatSpec!Char fmt) { if (fmt.spec == "s") return to!string((ip >>> 24) & 0xFF) ~ "." ~ to!string((ip >>> 16) & 0xFF) ~ "." ~ to!string((ip >>> 8) & 0xFF) ~ "." ~ to!string(ip & 0xFF); else // Fallback to usual uint-formatting return format("%s", ip); } T -- We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the Internet, we know this is not true. -- Robert Wilensk
Subtyping with alias this
Hello. I need subtype uint to store ipv4 address. It should be like ordinary uint, except conversion to string with %s format. My try https://run.dlang.io/is/fwTc0H failed on last assert: ``` struct IpV4Address { private uint ip; alias ip this; string toString() { import std.conv: to; return to!string((ip >>> 24) & 0xFF) ~ "." ~ to!string((ip >>> 16) & 0xFF) ~ "." ~ to!string((ip >>> 8) & 0xFF) ~ "." ~ to!string(ip & 0xFF); } } void main() { import std.format: format; IpV4Address x; x = 0x01020304; // 1.2.3.4 assert( x == 0x01020304 ); assert( format("%s", x) == "1.2.3.4" ); assert( format("%x", x) == "01020304" ); // FAILED /+ std.format.FormatException@/dlang/dmd-nightly/linux/bin64/../../src/phobos/std/format.d(4065): Expected '%s' format specifier for type 'IpV4Address' +/ } ``` Is my goal (subtype should be normal uint, but with pretty to-string conversion) possible? Thanks.
Re: Template: get function name
On Monday, 17 August 2020 at 10:11:29 UTC, MoonlightSentinel wrote: On Monday, 17 August 2020 at 09:59:21 UTC, novice3 wrote: On Monday, 17 August 2020 at 09:45:55 UTC, novice3 wrote: access violation occur. reduced code https://run.dlang.io/is/U58t9R The wrapper parameters don't inherit the storage classes from the wrapped function. Try using std.traits.Parameters instead: https://run.dlang.io/is/wTyJWD. Nice, it works!
Re: Template: get function name
On Monday, 17 August 2020 at 09:59:21 UTC, novice3 wrote: On Monday, 17 August 2020 at 09:45:55 UTC, novice3 wrote: access violation occur. reduced code https://run.dlang.io/is/U58t9R The wrapper parameters don't inherit the storage classes from the wrapped function. Try using std.traits.Parameters instead: https://run.dlang.io/is/wTyJWD. ``` import std.traits : Parameters; void test(out int x) { x = 42; } void call (alias fn)(Parameters!fn args) { fn(args); } void main() { int a; a = 111; test(a); assert(a == 42); a = 222; call!test(a); assert(a == 42); } ```
Re: Template: get function name
On Monday, 17 August 2020 at 09:45:55 UTC, novice3 wrote: access violation occur. reduced code https://run.dlang.io/is/U58t9R void test(out int x) { x = 42; } void call (alias fn, Args ...)(Args args) { fn(args); } void main(){ int a; a = 111; test(a); assert(a == 42); // OK a = 222; call!test(a); assert(a == 42); // FAIL }
Re: Template: get function name
On Monday, 17 August 2020 at 08:55:49 UTC, Simen Kjærås wrote: Take the function as an alias parameter and wrap the entire call: Simen, for some reasons, your code dont respect api arg with "out" attribute. For example, i have ``` extern (Windows) DhcpEnumServers( in DWORDFlags, // must be zero in LPVOID IdInfo,// must be NULL out LPDHCP_SERVER_INFO_ARRAY Servers, // output servers list in LPVOID CallbackFn,// must be NULL in LPVOID CallbackData // must be NULL ); ``` and then i use it: ``` LPDHCP_SERVER_INFO_ARRAY servers; denforce!DhcpEnumServers(0, null, servers, null, null); ``` access violation occur. In disassembler we can see that servers parameter passed by value (initial 0 instead of address). In my earler code it wass passed properly, by ref. May be this not matter of your code, and i can bypass it by change extern declaration to LPDHCP_SERVER_INFO_ARRAY *Servers, but it will be interest to know the reasons... Any way, tnaks you for your code, i will use it.
Re: Template: get function name
On Monday, 17 August 2020 at 08:55:49 UTC, Simen Kjærås wrote: Take the function as an alias parameter and wrap the entire call: auto denforce(alias fn, string file = __FILE__, size_t line = __LINE__, Args...)(Args args) Thank you, Simen!
Re: Template: get function name
On Monday, 17 August 2020 at 08:07:32 UTC, novice3 wrote: Hello. I have wrapping Windows API functions, wich return 0 on success and erroro code on failure. I copy wenforce template as: ``` private T denforce(T, S)(T value, lazy S msg = null, string file = __FILE__, size_t line = __LINE__) { import core.sys.windows.winerror: NO_ERROR; import std.conv: to; if (value != NO_ERROR) throw new WindowsException(value, to!string(msg), file, line); return value; } ``` and use it: ``` DhcpEnumServers(0, null, servers, null, null).denforce("DhcpEnumServers"); Then windows api - extern (Windows)DhcpEnumServers - return error, then Windows exception throwed with name of failed api "DhcpEnumServers". Can we change template to avoid api name dublicate? Can denforce template obtain "DhcpEnumServers" function name to format message "DhcpEnumServers api failed"? Thanks. Take the function as an alias parameter and wrap the entire call: auto denforce(alias fn, string file = __FILE__, size_t line = __LINE__, Args...)(Args args) { import core.sys.windows.winerror: NO_ERROR; auto value = fn(args); if (value != NO_ERROR) { throw new WindowsException(value, __traits(identifier, fn)~" api call failed.", file, line); } return value; } unittest { denforce!DhcpEnumServers(0, null, servers, null, null); } For bonus points, you could also get the error message for the returned error code: string convertErrorCode(uint code) { import core.sys.windows.winbase : FormatMessage, LoadLibrary, FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS, FORMAT_MESSAGE_FROM_HMODULE; wchar[512] buf; auto written = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, code, 0, buf.ptr, buf.length, null); if (!written) { auto inst = LoadLibrary("Ntdsbmsg.dll"); if (inst) { written = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, inst, code, 0, buf.ptr, buf.length, null); } } if (written) { import std.conv : to; return buf.ptr.to!string; } else { import std.format : format; return format("An unknown error occured: %x", code); } } unittest { import core.sys.windows.winerror : ERROR_INVALID_FUNCTION; import std.stdio; writeln(convertErrorCode(ERROR_INVALID_FUNCTION)); writeln(convertErrorCode(1234567891)); } -- Simen
Template: get function name
Hello. I have wrapping Windows API functions, wich return 0 on success and erroro code on failure. I copy wenforce template as: ``` private T denforce(T, S)(T value, lazy S msg = null, string file = __FILE__, size_t line = __LINE__) { import core.sys.windows.winerror: NO_ERROR; import std.conv: to; if (value != NO_ERROR) throw new WindowsException(value, to!string(msg), file, line); return value; } ``` and use it: ``` DhcpEnumServers(0, null, servers, null, null).denforce("DhcpEnumServers"); Then windows api - extern (Windows)DhcpEnumServers - return error, then Windows exception throwed with name of failed api "DhcpEnumServers". Can we change template to avoid api name dublicate? Can denforce template obtain "DhcpEnumServers" function name to format message "DhcpEnumServers api failed"? Thanks.