www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Trouble creating bidirectional range

reply Martin Drasar <drasar ics.muni.cz> writes:
Hi,

I have upgraded to dmd 2.063.2 and have some troubles making my custom
bidirectional range work (it used to). In fact, even this code fails on
assert and I am not really sure why...

import std.range;

struct MyRange(T)
{
  private:
  T[] data;

  public:
  T front()  property { return data[0]; }
  T back()   property { return data[0]; }
  void popFront() {}
  void popBack()  {}
  bool empty()  property { return false; }
  auto save()
  {
    typeof(this) result;
    result.data = data;
    return result;
  }
}

static this()
{
  MyRange!string tmp;
  static assert(isInputRange!(MyRange!string));
  static assert(is(typeof(tmp.save) == MyRange!string));
}

I get this when trying to compile:

 drasar uriel:/tmp$ dmd test.d
 test.d(26): Error: static assert  (is(pure nothrow  safe MyRange!(string)() ==
MyRange!(string))) is false
Do you have an idea? Thanks, Martin
Sep 29 2013
next sibling parent reply "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
On Sunday, 29 September 2013 at 20:37:13 UTC, Martin Drasar wrote:
   static assert(is(typeof(tmp.save) == MyRange!string));
You should call it like this: static assert(is(typeof(tmp.save()) == MyRange!string));
Sep 29 2013
parent reply "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
On Sunday, 29 September 2013 at 20:42:20 UTC, Andrej Mitrovic 
wrote:
 On Sunday, 29 September 2013 at 20:37:13 UTC, Martin Drasar 
 wrote:
  static assert(is(typeof(tmp.save) == MyRange!string));
You should call it like this: static assert(is(typeof(tmp.save()) == MyRange!string));
Btw, as for the reason why that used to work, I think it's one of these: In earlier versions typeof() might have checked the return type of the function, rather than the type of the function itself. And purity (and other attributes) are now inferred for functions in templated aggregates. (but it may not be related to your code).
Sep 29 2013
parent Martin Drasar <drasar ics.muni.cz> writes:
On 29.9.2013 22:45, Andrej Mitrovic wrote:
 On Sunday, 29 September 2013 at 20:42:20 UTC, Andrej Mitrovic wrote:
 On Sunday, 29 September 2013 at 20:37:13 UTC, Martin Drasar wrote:
  static assert(is(typeof(tmp.save) == MyRange!string));
You should call it like this: static assert(is(typeof(tmp.save()) == MyRange!string));
Btw, as for the reason why that used to work, I think it's one of these: In earlier versions typeof() might have checked the return type of the function, rather than the type of the function itself. And purity (and other attributes) are now inferred for functions in templated aggregates. (but it may not be related to your code).
Hi Andrej, this is just a copy&paste of code from std.range documentation. In fact, the plain isForwardRange fails. It was just expanded to show where it fails. Btw, I have this in range.d isForwardRange check: static assert (is(typeof(r1.save) == R)); Does that mean that the std.range code is wrong? Martin
Sep 29 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/29/2013 10:25 PM, Martin Drasar wrote:
 Hi,

 I have upgraded to dmd 2.063.2 and have some troubles making my custom
 bidirectional range work (it used to). In fact, even this code fails on
 assert and I am not really sure why...
...
 I get this when trying to compile:

 drasar uriel:/tmp$ dmd test.d
 test.d(26): Error: static assert  (is(pure nothrow  safe MyRange!(string)() ==
MyRange!(string))) is false
Do you have an idea? Thanks, Martin
Mark 'save' with property and it will work.
Sep 29 2013
parent reply Martin Drasar <drasar ics.muni.cz> writes:
On 29.9.2013 23:19, Timon Gehr wrote:
 Mark 'save' with  property and it will work.
Well, d'oh! It really works now, thanks Timon. And the documentation does not call it as a function anywhere. But... having save a property seems counterintuitive, at least on semantic level. Martin
Sep 29 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 30 September 2013 at 06:24:22 UTC, Martin Drasar wrote:
 On 29.9.2013 23:19, Timon Gehr wrote:
 Mark 'save' with  property and it will work.
Well, d'oh! It really works now, thanks Timon. And the documentation does not call it as a function anywhere. But... having save a property seems counterintuitive, at least on semantic level. Martin
Too late to change it now, but agreed. The new property rules mean you can easily make it a non-property and break nothing, but calling save with parrens in generic code will not be possible.
Sep 29 2013
parent Martin Drasar <drasar ics.muni.cz> writes:
On 30.9.2013 8:28, monarch_dodra wrote:
 Too late to change it now, but agreed.
 
 The new property rules mean you can easily make it a non-property and
 break nothing, but calling save with parrens in generic code will not be
 possible.
I don't doubt there is a good reason, however it should be probably better reflected in the documentation. There the 'popBack', 'save', etc. are reffered to only as primitives and the rest is left as an excersise for the reader. Martin
Sep 30 2013