Re: Constructing a variadic template parameter with source in two files
On 12/21/2016 07:59 PM, Jon Degenhardt wrote: > construct the 'opts' parameter from > definitions stored in two or more files. The reason for doing this is to > create a customization mechanism where-by there are a number of default > capabilities built-in to the main code base, but someone can customize > their copy of the code, putting definitions in a separate file, and have > it added in at compile time, including modifying command line arguments. I'm not sure this is any better than your mixin solution but getopt can be called multiple times on the same arguments. So, for example common code can parse them for its arguments and special code can parse them for its arguments. Useful bits: * std.getopt.config.passThrough allows unrecognized arguments * Although main's args can be passed to any function, program arguments are also available through Runtime.args() The following program calls getopt twice. import core.runtime : Runtime; import std.getopt; void foo() { int special; // Making a copy as Runtime.args() seems to return rvalue and getopt takes by-ref auto progArgs = Runtime.args(); getopt(progArgs, std.getopt.config.passThrough, "special", &special); } void main(string[] args) { int length; getopt(args, std.getopt.config.passThrough, "length", &length); } Ali
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 17:49:22 UTC, kinke wrote: Basic stuff such as this is appropriately tested. The named return value optimization is enforced by D (incl. unoptimized builds), so behavior doesn't change by this optimization. It's you who changed the behavior by removing the if. Due to the `if`, the compiler doesn't know whether it should construct `a` or `b` directly into the memory (sret pointee) provided by the caller. When omitting the `if`, it's clear that `b` is returned in all cases, so the compiles constructs `a` on the local stack (and destructs it before exiting the function), but emplaces `b` into `*sret` (i.e., the caller's stack) and can thus elide 1x postblit + 1x dtor. Thanks a lot. It makes sense. It seemed just weired that a conditional return value causes such a change. But I begin to understand the background.
Constructing a variadic template parameter with source in two files
I'd like to find a way to define programming constructs in one file and reference them in a getopt call defined in another file. getopt uses variadic template argument, so the argument list must be known at compile time. The std.getopt.getopt signature: GetoptResult getopt(T...)(ref string[] args, T opts) So, what I'm trying to do is construct the 'opts' parameter from definitions stored in two or more files. The reason for doing this is to create a customization mechanism where-by there are a number of default capabilities built-in to the main code base, but someone can customize their copy of the code, putting definitions in a separate file, and have it added in at compile time, including modifying command line arguments. I found a way to do this with a mixin template, shown below. However, it doesn't strike me as a particularly modular design. My question - Is there a better approach? The solution I identified is below. The '--say-hello' option is built-in (defined in app.d), the '--say-hello-world' command is defined in custom_commands.d. Running: $ ./app --say-hello --say-hello-world will print: Hello Hello World Which is the goal. But, is there a better way? Help appreciated. --Jon === command_base.d === /* API for defining "commands". */ interface Command { string exec(); } class BaseCommand : Command { private string _result; this (string result) { _result = result; } final string exec() { return _result; } } === custom_commands.d === /* Defines custom commands and a mixin for generating the getopt argument. * Note that 'commandArgHandler' is defined in app.d, not visible in this file. */ import command_base; class HelloWorldCommand : BaseCommand { this() { super("Hello World"); } } mixin template CustomCommandDeclarations() { import std.meta; auto pHelloWorldHandler = &commandArgHandler!HelloWorldCommand; alias CustomCommandOptions = AliasSeq!( "say-hello-world", "Print 'hello world'.", pHelloWorldHandler, ); } === app.d === /* This puts it all together. It creates built-in commands and uses the mixin from * custom_commands.d to declare commands and construct the getopt argument. */ import std.stdio; import command_base; class HelloCommand : BaseCommand { this() { super("Hello"); } } struct CmdOptions { import std.meta; Command[] commands; void commandArgHandler(DerivedCommand : BaseCommand)() { commands ~= new DerivedCommand(); } bool processArgs (ref string[] cmdArgs) { import std.getopt; import custom_commands; auto pHelloHandler = &commandArgHandler!HelloCommand; alias BuiltinCommandOptions = AliasSeq!( "say-hello", "Print 'hello'.", pHelloHandler, ); mixin CustomCommandDeclarations; auto CommandOptions = AliasSeq!(BuiltinCommandOptions, CustomCommandOptions); auto r = getopt(cmdArgs, CommandOptions); if (r.helpWanted) defaultGetoptPrinter("Options:", r.options); return !r.helpWanted; // Return true if execution should continue } } void main(string[] cmdArgs) { CmdOptions cmdopt; if (cmdopt.processArgs(cmdArgs)) foreach (cmd; cmdopt.commands) writeln(cmd.exec()); }
Re: Variadic function parameters passed by move
On 12/21/2016 02:59 PM, Nordlöw wrote: On Wednesday, 21 December 2016 at 21:02:17 UTC, Ali Çehreli wrote: void f(Rs...)(Rs ranges) { import std.functional: forward; g(forward!ranges); Interesting. How does this differ from std.algorithm.mutation.move() when R.length is 1? Why do we have both `move` and `forward`, then? Here is what I understand after glancing the documentation again: * 'move' is for moving state, which may necessitate destroying the source if leaving it behind can cause harm. For example, if the object has a destructor or post-blit, then the source should be "silenced" :) to prevent doing it twice. * As an added bonus, 'move' seems to be one spot (the only?) that D validates that a struct object does not have internal pointers. * 'forward' is for forwarding arguments to functions. It seems to an answer to "perfect forwarding" that I know from C++: maintain by-ref'ness of arguments when forwarding them to other functions. Ali
Re: Variadic function parameters passed by move
On Wednesday, 21 December 2016 at 23:11:02 UTC, Nordlöw wrote: Given that ref isn't involved, assuming that nothing else after the call to g references ranges, the compiler should move the values in ranges when it calls g Yes, DMD should automatically convert the last reference of a value expression to an r-value. This, most likely, involves calling doCopyOrMove() on the correct AST node somewhere in dmd/src/expression.d. But I haven't figure out how to do this. I have and idea outlined here: https://github.com/nordlow/dmd/commit/d3053e7801e340541bba32172718c2bb3de966c0 But I need feedback from the kernel developers on how go forward with this. Specifically the visitor that finds the last reference of a symbol that can be passed by move (non-reference) parameter in current function (scope). Do you have any clue on how to most easily find detect whether a SymbolExpression is the last reference to that symbol in the scope of the symbol definition, Jonathan? If this gets fixed we will have yet another way of programming with ranges in D that will require neither RC nor GC!
Re: Variadic function parameters passed by move
On Wednesday, 21 December 2016 at 21:09:41 UTC, Jonathan M Davis wrote: Given that ref isn't involved, assuming that nothing else after the call to g references ranges, the compiler should move the values in ranges when it calls g, so I would have hoped that the compiler would then allow you to call g with some of the values being non-copyable, but maybe it's not that forgiving right now for some reason. I can't actually test anything at the moment though, so I don't know what it will and won't actually allow you to do - just what it should be able to allow you to do given what it does with implicit moves. My plan: https://github.com/dlang/phobos/pull/4971
Re: Variadic function parameters passed by move
On Wednesday, 21 December 2016 at 21:02:17 UTC, Ali Çehreli wrote: void f(Rs...)(Rs ranges) { import std.functional: forward; g(forward!ranges); Interesting. How does this differ from std.algorithm.mutation.move() when R.length is 1? Why do we have both `move` and `forward`, then?
Re: Variadic function parameters passed by move
On Wednesday, December 21, 2016 20:27:47 Nordlöw via Digitalmars-d-learn wrote: > If I have a variadic function > > f(Rs...)(Rs ranges) > { > g(ranges); > } > > that calls > > g(Rs...)(Rs ranges) > { > // use ranges > } > > and all or some of the elements in `ranges` are non-copyable can > I somehow move them at the call of `g` inside of `f`. > > I've tried > > f(Rs...)(Rs ranges) > { > import std.algorithm.mutation : move; > g(move(ranges)); > } > > but that does't work. Given that ref isn't involved, assuming that nothing else after the call to g references ranges, the compiler should move the values in ranges when it calls g, so I would have hoped that the compiler would then allow you to call g with some of the values being non-copyable, but maybe it's not that forgiving right now for some reason. I can't actually test anything at the moment though, so I don't know what it will and won't actually allow you to do - just what it should be able to allow you to do given what it does with implicit moves. - Jonathan M Davis
Re: Variadic function parameters passed by move
On 12/21/2016 12:27 PM, Nordlöw wrote: If I have a variadic function f(Rs...)(Rs ranges) { g(ranges); } that calls g(Rs...)(Rs ranges) { // use ranges } and all or some of the elements in `ranges` are non-copyable can I somehow move them at the call of `g` inside of `f`. I've tried f(Rs...)(Rs ranges) { import std.algorithm.mutation : move; g(move(ranges)); } but that does't work. At least compiles. :) void f(Rs...)(Rs ranges) { import std.functional: forward; g(forward!ranges); } void g(Rs...)(Rs ranges) { // use ranges } struct S { @disable this(this); } void main() { f(1, S()); } Ali
Variadic function parameters passed by move
If I have a variadic function f(Rs...)(Rs ranges) { g(ranges); } that calls g(Rs...)(Rs ranges) { // use ranges } and all or some of the elements in `ranges` are non-copyable can I somehow move them at the call of `g` inside of `f`. I've tried f(Rs...)(Rs ranges) { import std.algorithm.mutation : move; g(move(ranges)); } but that does't work.
Re: Selective unittesting in DUB
On 2016-12-21 19:07, Nordlöw wrote: Is there a way to specify in dub.json (or any other file) that only a subset of the sources compiled and linked to a library or app should have they're unittests enabled? You can use the "unittest" configuration in Dub to add or remove files, but I don't think you can disable some of the unittest blocks in a single module. There's also unit-threaded [1] which allows you to run specific unit tests. [1] https://github.com/atilaneves/unit-threaded -- /Jacob Carlborg
Re: returning struct, destructor
On 12/21/2016 07:01 AM, Eugene Wissner wrote: > Isn't an optimization that changes the behavior bad? I had a crash in > the code where the destructor did something meaningfull, freed the > memory (the same pointer) twice. Sounds like you ended up with two objects that owned the same resource. You can either '@disable this(this)' so that copies of this type are not allowed or you can handle the resource in a different way: Make a copy of the resource in this(this) so the two copies have their own separate resources, leave the resource to the GC, use reference counting, etc. Ali
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 18:02:54 UTC, bauss wrote: It removes an unnecessary allocation for the returning copy of the struct, as the return value is never used. Hence why it's pointless that it would be compiled anyway. That's incorrect, it doesn't have anything to do with the return value being used or not.
Selective unittesting in DUB
Is there a way to specify in dub.json (or any other file) that only a subset of the sources compiled and linked to a library or app should have they're unittests enabled?
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 15:01:20 UTC, Eugene Wissner wrote: On Wednesday, 21 December 2016 at 14:15:06 UTC, John C wrote: On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Possibly to do with named return value optimisation. Isn't an optimization that changes the behavior bad? I had a crash in the code where the destructor did something meaningfull, freed the memory (the same pointer) twice. It isn't an optimization that changes behavior. It removes an unnecessary allocation for the returning copy of the struct, as the return value is never used. Hence why it's pointless that it would be compiled anyway.
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 15:01:20 UTC, Eugene Wissner wrote: On Wednesday, 21 December 2016 at 14:15:06 UTC, John C wrote: On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Possibly to do with named return value optimisation. Isn't an optimization that changes the behavior bad? I had a crash in the code where the destructor did something meaningfull, freed the memory (the same pointer) twice. Basic stuff such as this is appropriately tested. The named return value optimization is enforced by D (incl. unoptimized builds), so behavior doesn't change by this optimization. It's you who changed the behavior by removing the if. Due to the `if`, the compiler doesn't know whether it should construct `a` or `b` directly into the memory (sret pointee) provided by the caller. When omitting the `if`, it's clear that `b` is returned in all cases, so the compiles constructs `a` on the local stack (and destructs it before exiting the function), but emplaces `b` into `*sret` (i.e., the caller's stack) and can thus elide 1x postblit + 1x dtor.
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 14:15:06 UTC, John C wrote: On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Possibly to do with named return value optimisation. Isn't an optimization that changes the behavior bad? I had a crash in the code where the destructor did something meaningfull, freed the memory (the same pointer) twice.
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 14:15:06 UTC, John C wrote: On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Possibly to do with named return value optimisation. looks like it is really optimized away. an "improved" test case, even with "if" block removed or changed to true now it always the same number of operations == import std.stdio; import std.conv : to; struct A { int num; this(int n) { num = n; } this(const ref A other) { num = -1; // special case writeln("copy of " ~ to!string(other.num)); } ~this() { writeln("Destruct" ~ to!string(num)); } } A myFunc() { auto a = A(1), b = A(2); if (false) { return A(a); } return A(b); } void main() { myFunc(); }
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Possibly to do with named return value optimisation.
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 12:32:51 UTC, Nicholas Wilson wrote: On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: Consider we have a function that returns a struct. So for example: import std.stdio; struct A { ~this() { writeln("Destruct"); } } A myFunc() { auto a = A(), b = A(); if (false) { return a; } return b; } void main() { myFunc(); } This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Thx Structs are value types, so unless they you pass them by pointer/reference, they get copied. in myFunc it prints "Destruct" twice, one for a and once for b. In main it prints it one more for the (discarded) A returned from myfunc. Why if the "if block" is removed, the code prints "Destruct" only two times. One because "a" goes out of scope and one in the main function. I don't understand, why "if (false) ..." changes the behavior
Re: returning struct, destructor
On Wednesday, 21 December 2016 at 11:45:18 UTC, Eugene Wissner wrote: Consider we have a function that returns a struct. So for example: import std.stdio; struct A { ~this() { writeln("Destruct"); } } A myFunc() { auto a = A(), b = A(); if (false) { return a; } return b; } void main() { myFunc(); } This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Thx Structs are value types, so unless they you pass them by pointer/reference, they get copied. in myFunc it prints "Destruct" twice, one for a and once for b. In main it prints it one more for the (discarded) A returned from myfunc.
Re: BitArray Slicing
On Wednesday, 21 December 2016 at 12:00:57 UTC, Ezneh wrote: On Wednesday, 21 December 2016 at 11:49:06 UTC, Ilya Yaroshenko wrote: [...] Thanks, I'll check that solution to see if it fits my needs. As an off-topic question, is there any plan in Mir to implement the Tiny Mersenne Twister[1] algorithm (or a wrapper for it) ? [1] http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html You are the first who is interested TINYMT, feel free to open a PR in Mir Random https://github.com/libmir/mir-random TINYMT should not be big, only Engine itself is required (without floating point stuff and arrays generators).
Re: BitArray Slicing
On Wednesday, 21 December 2016 at 11:49:06 UTC, Ilya Yaroshenko wrote: On Wednesday, 21 December 2016 at 09:08:51 UTC, Ezneh wrote: Hi, in one of my projects I have to get a slice from a BitArray. I am trying to achieve that like this : void foo(BitArray ba) { auto slice = ba[0..3]; // Assuming it has more than 4 elements } The problem is that I get an error : "no operator [] overload for type BitArray". Is there any other way to get a slice from a BitArray ? Thanks, Ezneh. Mir allows you to define simple alternative to BitArray: https://github.com/libmir/mir -- struct BitMap { size_t* ptr; import core.bitop; bool opIndex(size_t index) const { return bt(ptr, index) != 0; } void opIndexAssign(bool val, size_t index) { if(val) bts(ptr, index); else btr(ptr, index); } } import mir.ndslice; void main() { auto arr = new size_t[3]; auto sl = BitMap(arr.ptr).sliced(size_t.sizeof * 8 * arr.length); sl[4] = true; sl[100] = true; sl.popFrontN(3); assert(sl[1]); assert(sl[97]); auto sl2 = sl[1...3]; // slicing } -- Thanks, I'll check that solution to see if it fits my needs. As an off-topic question, is there any plan in Mir to implement the Tiny Mersenne Twister[1] algorithm (or a wrapper for it) ? [1] http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html
Re: BitArray Slicing
On Wednesday, 21 December 2016 at 09:08:51 UTC, Ezneh wrote: Hi, in one of my projects I have to get a slice from a BitArray. I am trying to achieve that like this : void foo(BitArray ba) { auto slice = ba[0..3]; // Assuming it has more than 4 elements } The problem is that I get an error : "no operator [] overload for type BitArray". Is there any other way to get a slice from a BitArray ? Thanks, Ezneh. Mir allows you to define simple alternative to BitArray: https://github.com/libmir/mir -- struct BitMap { size_t* ptr; import core.bitop; bool opIndex(size_t index) const { return bt(ptr, index) != 0; } void opIndexAssign(bool val, size_t index) { if(val) bts(ptr, index); else btr(ptr, index); } } import mir.ndslice; void main() { auto arr = new size_t[3]; auto sl = BitMap(arr.ptr).sliced(size_t.sizeof * 8 * arr.length); sl[4] = true; sl[100] = true; sl.popFrontN(3); assert(sl[1]); assert(sl[97]); auto sl2 = sl[1...3]; // slicing } --
returning struct, destructor
Consider we have a function that returns a struct. So for example: import std.stdio; struct A { ~this() { writeln("Destruct"); } } A myFunc() { auto a = A(), b = A(); if (false) { return a; } return b; } void main() { myFunc(); } This prints 3 times "Destruct" with dmd 0.072.1. If I remove the if block, it prints "Destruct" only 2 times - the behavior I'm expecting. Why? Thx
Re: BitArray Slicing
On Wednesday, 21 December 2016 at 09:14:04 UTC, Eugene Wissner wrote: The problem is BitArray keeps multiple elements in one byte. You can't return just three bits but in the best case one byte with 8 elements. What could be done some internal range could be returned that gives access to the bits. But it isn't implemented. I see, so I have to find another way to get only the range I want from a BitArray.
Re: Swap front for char[] input ranges
On Monday, 19 December 2016 at 20:26:26 UTC, Ali Çehreli wrote: On 12/19/2016 06:09 AM, RazvanN wrote: > [...] wrote: >> [...] InputRanges. >> [...] following > [...] char[] > [...] function, so > [...] http://dlang.org/phobos/std_algorithm_mutation.html#bringToFront [...] No need to mention it. It is an honor to be able contribute to this great language. [...] That is right, I am working on that particular bug. After talking with AndreiA, I submitted this PR [1]. It treats the case of char[], but I am not really sure how the constraints should be applied to the function since it seems there are a lot of combinations (especially if char[] is supported). [1] https://github.com/dlang/phobos/pull/4970
Re: BitArray Slicing
On Wednesday, 21 December 2016 at 09:08:51 UTC, Ezneh wrote: Hi, in one of my projects I have to get a slice from a BitArray. I am trying to achieve that like this : void foo(BitArray ba) { auto slice = ba[0..3]; // Assuming it has more than 4 elements } The problem is that I get an error : "no operator [] overload for type BitArray". Is there any other way to get a slice from a BitArray ? Thanks, Ezneh. The problem is BitArray keeps multiple elements in one byte. You can't return just three bits but in the best case one byte with 8 elements. What could be done some internal range could be returned that gives access to the bits. But it isn't implemented.
BitArray Slicing
Hi, in one of my projects I have to get a slice from a BitArray. I am trying to achieve that like this : void foo(BitArray ba) { auto slice = ba[0..3]; // Assuming it has more than 4 elements } The problem is that I get an error : "no operator [] overload for type BitArray". Is there any other way to get a slice from a BitArray ? Thanks, Ezneh.