digitalmars.D.learn - Range with an alias parameter
- Alex (20/20) Jan 30 2019 Given this:
- Alex (27/47) Jan 30 2019 Ok... strange... it doesn't in fact... as this works:
- Steven Schveighoffer (18/32) Jan 30 2019 Apples and oranges :)
- Alex (4/22) Jan 31 2019 Yeah... maybe, it was too much code for a single day yesterday...
Given this: ´´´ import std.experimental.all; void main(){} static assert(isInputRange!(ReturnType!(produceS!(42))[])); auto produceS(size_t param)() { return S!param(); } struct S(size_t param) { // disable this(this); auto opIndex() { return produceRange!(this); } } auto produceRange(alias source)(){ return Range!source(); } struct Range(alias source) { size_t front(); void popFront(); bool empty(); } ´´´ Why disabling copying of S removes the range property of Range?
Jan 30 2019
On Wednesday, 30 January 2019 at 20:13:56 UTC, Alex wrote:Given this: ´´´ import std.experimental.all; void main(){} static assert(isInputRange!(ReturnType!(produceS!(42))[])); auto produceS(size_t param)() { return S!param(); } struct S(size_t param) { // disable this(this); auto opIndex() { return produceRange!(this); } } auto produceRange(alias source)(){ return Range!source(); } struct Range(alias source) { size_t front(); void popFront(); bool empty(); } ´´´ Why disabling copying of S removes the range property of Range?Ok... strange... it doesn't in fact... as this works: ´´´ import std.experimental.all; void main() { S!42 s; auto res = s[]; static assert(isInputRange!(typeof(res))); res.front.writeln; } //static assert(isInputRange!(ReturnType!(produceS!(42))[])); auto produceS(size_t param)() { return S!param(); } struct S(size_t param) { auto myParam(){return param; } disable this(this); auto opIndex() { return produceRange!(this); } } auto produceRange(alias source)(){ return Range!source(); } struct Range(alias source) { size_t front(){return source.myParam;} void popFront(); bool empty(); } ´´´
Jan 30 2019
On 1/30/19 3:56 PM, Alex wrote:Ok... strange... it doesn't in fact... as this works: ´´´ import std.experimental.all; void main() { S!42 s; auto res = s[]; static assert(isInputRange!(typeof(res))); res.front.writeln; } //static assert(isInputRange!(ReturnType!(produceS!(42))[]));Apples and oranges :) ReturnType!(produceS!(42)) is a TYPE, not a variable. When you apply the brackets, it's not calling your opindex, but rather changing it to an array. So let's make it clearer by saying: alias T = ReturnType!(produceS!(42)); So now, your assert becomes: static assert(isInputRange!(T[])); Which, is not coming up as a valid range, because you can't copy the front value (this(this) is disabled). In the other expression, you are first calling the index operator on an instance of the type, which returns a DIFFERENT type, and then asserting the type of that is an input range. The equivalent (still using T) is: static assert(isInputRange!(typeof(T.init[]))); replacing T with the original is: static assert(isInputRange!(typeof(ReturnType!(produceS!(42)).init[]))); -Steve
Jan 30 2019
On Thursday, 31 January 2019 at 02:41:00 UTC, Steven Schveighoffer wrote:Apples and oranges :) ReturnType!(produceS!(42)) is a TYPE, not a variable. When you apply the brackets, it's not calling your opindex, but rather changing it to an array. So let's make it clearer by saying: alias T = ReturnType!(produceS!(42)); So now, your assert becomes: static assert(isInputRange!(T[])); Which, is not coming up as a valid range, because you can't copy the front value (this(this) is disabled). In the other expression, you are first calling the index operator on an instance of the type, which returns a DIFFERENT type, and then asserting the type of that is an input range. The equivalent (still using T) is: static assert(isInputRange!(typeof(T.init[]))); replacing T with the original is: static assert(isInputRange!(typeof(ReturnType!(produceS!(42)).init[]))); -SteveYeah... maybe, it was too much code for a single day yesterday... :P
Jan 31 2019