Re: input range with non copyable element
On Monday, 9 August 2021 at 02:47:40 UTC, Mathias LANG wrote: On Sunday, 8 August 2021 at 18:36:02 UTC, vit wrote: Hello, is there reason why elements of input range must be copyable? By design, not that I can think of. But it is assumed all over the place, unfortunately. You can make your `front` method return by `ref`, but you're still going to get bitten as soon as you do any `std.algorithm`-based operation, as storage classes are not inferred (https://issues.dlang.org/show_bug.cgi?id=9423) and things get passed by value to your delegates by default. The problem can also show up when you `foreach` over a range (https://issues.dlang.org/show_bug.cgi?id=15413). And finally, `std.algorithm` need to support it. So currently you'll have to jump through a lot of hops to get it to work. It'll be much easier to use your own `map` & co to get the job done for the time being. Hopefully at some point in the near future that won't be needed anymore. Look like I am not the first who has this problem: https://issues.dlang.org/show_bug.cgi?id=14478 I copy part of `std.algorithm` I use and change `isInputRange` to: ```d enum bool isInputRange(R) = true && is(typeof(R.init) == R) ///no change && is(ReturnType!((R r) => r.empty) == bool) ///no change && is(typeof((return ref R r) => (auto ref x){}(r.front))) ///Before: , is(typeof((return ref R r) => r.front)) && !is(ReturnType!((R r) => r.front) == void) ///no change && is(typeof((R r) => r.popFront)); ///no change
Re: input range with non copyable element
On Sunday, 8 August 2021 at 18:36:02 UTC, vit wrote: Hello, is there reason why elements of input range must be copyable? By design, not that I can think of. But it is assumed all over the place, unfortunately. You can make your `front` method return by `ref`, but you're still going to get bitten as soon as you do any `std.algorithm`-based operation, as storage classes are not inferred (https://issues.dlang.org/show_bug.cgi?id=9423) and things get passed by value to your delegates by default. The problem can also show up when you `foreach` over a range (https://issues.dlang.org/show_bug.cgi?id=15413). And finally, `std.algorithm` need to support it. So currently you'll have to jump through a lot of hops to get it to work. It'll be much easier to use your own `map` & co to get the job done for the time being. Hopefully at some point in the near future that won't be needed anymore.
input range with non copyable element
Hello, is there reason why elements of input range must be copyable? For example this example works and copy ctor is never called: ```d import std.algorithm : map; import std.range; struct Foo{ int i; this(scope ref typeof(this) rhs)pure nothrow @safe @nogc{ //this.i = rhs.i; assert(0, "no copy"); } @disable this(scope const ref typeof(this) rhs)pure nothrow @safe @nogc; } void main(){ Foo[] foos = [Foo(1), Foo(2), Foo(3)]; //this work (copy ctor is never called): { auto tmp = foos .map!((ref foo) => foo.i) .array; } } ``` This doesn't work: ```d void main(){ const(Foo)[] foos = [Foo(1), Foo(2), Foo(3)]; //error: { auto tmp = foos .map!((ref foo) => foo.i) .array; } } ``` Source of my problem is in `isInputRange`: ```d import std.range; import std.traits : ReturnType; alias R = const(Foo)[]; //enum bool isInputRange(R) = static assert(is(typeof(R.init) == R)); ///OK static assert(is(ReturnType!((R r) => r.empty) == bool)); ///OK static assert(is(typeof((return ref R r) => r.front)));///ERROR, copy result of front static assert(!is(ReturnType!((R r) => r.front) == void)); ///OK static assert(is(typeof((R r) => r.popFront))); ///OK ``` Is it possible to make lambda return `auto ref`?