www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Range with an alias parameter

reply Alex <sascha.orlov gmail.com> writes:
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
parent reply Alex <sascha.orlov gmail.com> writes:
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
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
parent Alex <sascha.orlov gmail.com> writes:
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[])));

 -Steve
Yeah... maybe, it was too much code for a single day yesterday... :P
Jan 31