www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Constraining template's function parameter signature

reply "Tommi" <tommitissari hotmail.com> writes:
I'm trying to constrain a struct template based on a parameter 
that's supposed be a function with a certain signature. Difficult 
to explain, easier just to show the problem:

module pseudorange;

struct PseudoInputRange(T, alias advance)
     //The next line doesn't compile
     //if (is(typeof(advance(T.init)) == void))
{
private:
     T m_front;
     T m_end;

public:
     this(T begin, T end) pure nothrow
     {
         m_front = begin;
         m_end = end;
     }

      property immutable(T) front() const pure nothrow
     {
         return m_front;
     }

     void popFront() pure nothrow
     {
         advance(m_front);
     }

      property bool empty() const pure nothrow
     {
         return m_front == m_end;
     }
}

//...

module main;

import std.stdio;
import std.range;
import pseudorange;

int main(string[] argv)
{
     alias PseudoInputRange!(int, (ref int x) {++x;}) MyRange;
     static assert(isInputRange!MyRange);

     foreach (x; MyRange(1, 11))
     {
         writeln(x);
     }
     stdin.readln();
     return 0;
}
Jun 14 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/14/2012 02:57 PM, Tommi wrote:
 I'm trying to constrain a struct template based on a parameter that's
 supposed be a function with a certain signature. Difficult to explain,
 easier just to show the problem:

 module pseudorange;

 struct PseudoInputRange(T, alias advance)
 //The next line doesn't compile
 //if (is(typeof(advance(T.init)) == void))
 ...
 alias PseudoInputRange!(int, (ref int x) {++x;}) MyRange;
 static assert(isInputRange!MyRange);

'T.init' is not an lvalue and can therefore not be passed by ref. You can fix the problem with the fewest keystrokes like this: if (is(typeof(advance([T.init][0])) == void))
Jun 14 2012