[Issue 18807] RefRange behaves very differently for Input Ranges and Forward Ranges

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18807

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P3  |P2

--


[Issue 21087] refRange() does not work with ranges which have internal const fields

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21087

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P1  |P3

--


[Issue 21087] New: refRange() does not work with ranges which have internal const fields

2020-07-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21087

  Issue ID: 21087
   Summary: refRange() does not work with ranges which have
internal const fields
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: andrej.mitrov...@gmail.com

```
import std.range;

public static auto byRange ()
{
static struct Range
{
size_t lbound = 0;
const size_t hbound = 100;

size_t length () const { return 0; }
bool empty () const { return false; }
int front () const { return 0; }
void popFront () { }
}

return Range(0);
}

void main ()
{
auto keys = byRange();
auto r = refRange();
}
```

$ dmd test.d
> /Library/D/dmd/src/phobos/std/range/package.d(11504,13): Error: cannot modify 
> struct instance `*this._range` of type `Range` because it contains `const` or 
> `immutable` members
> /Library/D/dmd/src/phobos/std/range/package.d(12215,16): Error: template 
> instance `std.range.RefRange!(Range)` error instantiating
test.d(22,22):instantiated from here: `refRange!(Range)`

As a workaround `hbound` can be declared an enum here.

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-12-18 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

berni44  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||bugzi...@d-ecke.de
 Resolution|--- |FIXED

--- Comment #8 from berni44  ---
The original problem has meanwhile been fixed as well as many others related.
If there are still some functions, that are not compatible with RefRange, IMHO
they should be addressed in a separate bug report; else we will never know, if
we can close this or not...

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-04-09 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #7 from Dlang Bot  ---
@wilzbach created dlang/phobos pull request #6951 "Merge remote-tracking branch
'upstream/stable' into merge_stable" mentioning this issue:

- make `chain` compatible with `RefRange`

  Part of a series on issue 18657.

- make `group` compatible with `RefRange`

  Part of a series on issue 18657.

- make `choose` compatible with `RefRange`

  Part of a series on issue 18657.

- make `cycle` compatible with `RefRange`

  Part of a series on issue 18657.

- make `splitter` compatible with `RefRange`

  Part of a series on issue 18657.

- make `roundRobin` compatible with `RefRange`

  Part of a series on issue 18657.

- make `until` compatible with `RefRange`

  Part of a series on issue 18657.

https://github.com/dlang/phobos/pull/6951

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-04-05 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #6 from Dlang Bot  ---
@MartinNowak created dlang/phobos pull request #6943 "Merge remote-tracking
branch 'upstream/stable' into merge_stable" mentioning this issue:

- make `chain` compatible with `RefRange`

  Part of a series on issue 18657.

- make `group` compatible with `RefRange`

  Part of a series on issue 18657.

- make `choose` compatible with `RefRange`

  Part of a series on issue 18657.

- make `cycle` compatible with `RefRange`

  Part of a series on issue 18657.

- make `splitter` compatible with `RefRange`

  Part of a series on issue 18657.

- make `roundRobin` compatible with `RefRange`

  Part of a series on issue 18657.

- make `until` compatible with `RefRange`

  Part of a series on issue 18657.

https://github.com/dlang/phobos/pull/6943

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-03-27 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #5 from Dlang Bot  ---
dlang/phobos pull request #6935 "make `cycle`, `splitter`, `roundRobin`, and
`until` compatible with `RefRange`" was merged into stable:

- 3ef957baf536b55fa9ebd93050e187f52e2c47f5 by aG0aep6G:
  make `cycle` compatible with `RefRange`

  Part of a series on issue 18657.

- 729f732fbc8716baa712ec9b5e645fc4919a9e78 by aG0aep6G:
  make `splitter` compatible with `RefRange`

  Part of a series on issue 18657.

- aeea9598bde91a9e42e5a5bad791ee3378d84e89 by aG0aep6G:
  make `roundRobin` compatible with `RefRange`

  Part of a series on issue 18657.

- bd47453b49cf93e77cf11972f4167b9fd420f58d by aG0aep6G:
  make `until` compatible with `RefRange`

  Part of a series on issue 18657.

https://github.com/dlang/phobos/pull/6935

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-03-26 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #4 from Dlang Bot  ---
@aG0aep6G created dlang/phobos pull request #6935 "make `cycle`, `splitter`,
`roundRobin`, and `until` compatible with `RefRange`" mentioning this issue:

- make `cycle` compatible with `RefRange`

  Part of a series on issue 18657.

- make `splitter` compatible with `RefRange`

  Part of a series on issue 18657.

- make `roundRobin` compatible with `RefRange`

  Part of a series on issue 18657.

- make `until` compatible with `RefRange`

  Part of a series on issue 18657.

https://github.com/dlang/phobos/pull/6935

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-03-26 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #3 from Dlang Bot  ---
dlang/phobos pull request #6346 "make `group`, `chain`, and `choose` compatible
with `RefRange`" was merged into stable:

- b1b8b7968ffda3d64f9ee4666ebe453311eeb66e by aG0aep6G:
  make `chain` compatible with `RefRange`

  Part of a series on issue 18657.

- e14ef1c912dcd84c197c03e7a8683e344559144b by aG0aep6G:
  make `group` compatible with `RefRange`

  Part of a series on issue 18657.

- be9020a369091f58c3e5b1f3f3d31441d402d3f1 by aG0aep6G:
  make `choose` compatible with `RefRange`

  Part of a series on issue 18657.

https://github.com/dlang/phobos/pull/6346

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2019-03-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #2 from Dlang Bot  ---
@aG0aep6G updated dlang/phobos pull request #6346 "make `group`, `chain`, and
`choose` compatible with `RefRange`" mentioning this issue:

- make `chain` compatible with `RefRange`

  Part of a series on issue 18657.

- make `group` compatible with `RefRange`

  Part of a series on issue 18657.

- make `choose` compatible with `RefRange`

  Part of a series on issue 18657.

https://github.com/dlang/phobos/pull/6346

--


[Issue 18807] RefRange behaves very differently for Input Ranges and Forward Ranges

2018-04-30 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18807

--- Comment #4 from Eyal <e...@weka.io> ---
Indeed, and both are worth fixing.

So I think it makes sense to keep these 2 issues:

issue 14619 should fix compiler's foreach behavior (calling opSlice
unnecessarily)

this issue should fix RefRange in phobos, to avoid defining opSlice().

--


[Issue 18807] RefRange behaves very differently for Input Ranges and Forward Ranges

2018-04-30 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18807

Steven Schveighoffer <schvei...@yahoo.com> changed:

   What|Removed |Added

 CC||schvei...@yahoo.com

--- Comment #3 from Steven Schveighoffer <schvei...@yahoo.com> ---
There are 2 issues here. One is the same from 14619 -- the compiler is assuming
opSlice  on a valid range is a no-op.

The second issue is that for some reason opSlice is defined in RefRange iff
save is defined. That makes no sense.

Fixing either of these issues will fix the problem I think.

--


[Issue 18807] RefRange behaves very differently for Input Ranges and Forward Ranges

2018-04-30 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18807

--- Comment #2 from Eyal <e...@weka.io> ---
It's related -- but that issue is about "foreach" behavior, and this issue is
about RefRange behavior, which probably should not define opSlice (as mentioned
in passing in issue 14619).

--


[Issue 18807] RefRange behaves very differently for Input Ranges and Forward Ranges

2018-04-29 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18807

ag0aep6g  changed:

   What|Removed |Added

 CC||ag0ae...@gmail.com
   See Also||https://issues.dlang.org/sh
   ||ow_bug.cgi?id=14619

--- Comment #1 from ag0aep6g  ---
Possibly a duplicate of issue 14619.

--


[Issue 18807] New: RefRange behaves very differently for Input Ranges and Forward Ranges

2018-04-29 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18807

  Issue ID: 18807
   Summary: RefRange behaves very differently for Input Ranges and
Forward Ranges
   Product: D
   Version: D2
  Hardware: All
   URL: http://dlang.org/
OS: All
Status: NEW
  Severity: major
  Priority: P3
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: e...@weka.io

Example program:

import std.range: refRange, iota;

struct R1 {
auto r = iota(3);
alias r this;
}
void works() {
R1 r1;
foreach(x; refRange()) {}
assert(r1.empty);
}

struct R2 {
auto r = iota(3);
alias r this;
@property auto save() { return this; }
}
void explodes() {
R2 r2;
import std.range;
foreach(x; refRange()) {}
assert(r2.empty);   // <-- BOOM
}

works() is fine.
explodes() fails on the assertion.

The only difference is that R2 defines save().

What happens is that the foreach calls opSlice (if it exists), which calls
save. opSlice exists iff save exists.

Upgrading an existing input range to a forward range invisibly breaks any code
that used foreach on a refRange of that range.

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2018-03-25 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

Carsten Blüggel  changed:

   What|Removed |Added

 CC||chi...@posteo.net

--


[Issue 18657] std.range and std.algorithm can't handle refRange

2018-03-25 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

--- Comment #1 from ag0aep6g <ag0ae...@gmail.com> ---
PR to fix the first three examples without touching RefRange:
https://github.com/dlang/phobos/pull/6346

--


[Issue 18657] New: std.range and std.algorithm can't handle refRange

2018-03-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18657

  Issue ID: 18657
   Summary: std.range and std.algorithm can't handle refRange
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: ag0ae...@gmail.com

Five examples:


void main()
{
import std.range: refRange;
import std.stdio;
{
import std.algorithm.iteration: group;
string s = "foo";
    auto r = refRange().group;
writeln(r.save);
/* Prints
"[Tuple!(dchar, uint)('f', 1), Tuple!(dchar, uint)('o', 2)]". Ok.
*/
writeln(r.save);
/* Should print the same as the line above. Actually prints
"[Tuple!(dchar, uint)('f', 1)]". */
}
{
import std.range: chain;
string s = "foo";
auto r = refRange().chain("bar");
writeln(r.save); /* Should print "foobar". Actually prints "bar". */
}
{
import std.range: choose;
string s = "foo";
auto r = choose(true, refRange(), "bar");
writeln(r); /* Should print "foo". Actually prints nothing. */
    }
{
import std.range: cycle, take;
string s = "foo";
auto r = refRange().cycle.take(4);
writeln(r.save); /* Prints "foof". Ok. */
writeln(r.save); /* Should print "foof", too. Actually prints "oofo".
*/
}
{
import std.algorithm.iteration: splitter;
string s = "foobar";
auto r = refRange().splitter!(c => c == 'b');
writeln(r.save); /* Prints "[foo, ar]". Ok. */
writeln(r.save);
    /* Should print the same. Actually crashes with an AssertError. */
}
}


Most probably, there are more Phobos functions that can't handle refRange. I
haven't checked them all.

The root of the problem is RefRange's opAssign. Instead of just changing the
reference, it actually overwrites the referenced range. That leads to
surprising behavior:


void main()
{
import std.range;
import std.stdio;

string s = "foo";
auto r = refRange();

auto r2 = r;
r2 = r2.save;
/* Surprising: Effectively just does `s = s;` (i.e., nothing). */

r2.popFront();
writeln(r); /* Surprising: Prints "oo". */
}


Note that `r2 = r; r2 = r2.save;` is what you typically do in a postblit
function.

If RefRange's custom opAssign is removed, all the examples just work.
Unfortunately, the surprising behavior is deliberate, and not just a bug. The
docs on RefRange.opAssign say [1]:

> This does not assign the pointer of rhs to this RefRange.
> Rather it assigns the range pointed to by rhs to the range pointed
> to by this RefRange. This is because any operation on a RefRange is
> the same is if it occurred to the original range.

The issue comes down to whether RefRange should be allowed to have its funky
opAssign, or if range-handling code should be allowed to assume that assignment
does the obvious thing.


[1] https://dlang.org/phobos/std_range.html#.RefRange.opAssign

--


Re: RefRange behavior

2018-03-14 Thread Alex via Digitalmars-d-learn

On Wednesday, 14 March 2018 at 10:22:45 UTC, Alex wrote:

Is there a simple workaround, maybe?


ok, the workaround would be to enumerate the member and to use 
the former notation.




RefRange behavior

2018-03-14 Thread Alex via Digitalmars-d-learn

Hi all,
given this:

´´´
import std.range;

size_t[] arr;

struct S
{
RefRange!(size_t[]) member;
}

void fun(ref size_t numByRef){}

void main()
{
arr.length = 42;
S s;
s.member = refRange();
static assert(__traits(compiles, fun(s.member[0])));
static assert(!__traits(compiles, fun(s.member.front)));
//fun(s.member.front);
/*
	source/app.d(19,5): Error: function `app.fun(ref ulong 
numByRef)` is not callable using argument types `(ulong)`
	source/app.d(19,5):cannot pass rvalue argument 
`s.member.front()` of type `ulong` to parameter `ref ulong 
numByRef`

*/
}
´´´

Why does the last static assert yields false? Is there a simple 
workaround, maybe?


Re: refRange with non copyable struct

2017-04-17 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, April 17, 2017 19:39:25 Stanislav Blinov via Digitalmars-d-learn 
wrote:
> On Monday, 17 April 2017 at 19:00:44 UTC, Jonathan M Davis wrote:
> > Because otherwise, it's not acting like a reference to the
> > original range, which is the whole point of RefRange. The
> > correct solution would probably be to @disable opAssign in the
> > case where the original range can't be overwritten by another
> > range.
>
> This doesn't look quite right. References in D are rebindable.
> That is, assigning a reference to a reference does not copy
> referenced object, only the reference itself.
> It seems that RefRange is trying to impersonate a C++ reference.

The term reference in D is a bit overloaded. The whole point of RefRange is
to have the original range affected by everything that happens to the new
range as if it were the original range - which is what happens with ref
(which is not rebindable) except that ref only works on parameters and
return types. So, yes, it is similar to a C++ reference. It's not trying to
be a pointer, which is more like what a class reference is.

- Jonathan M Davis



Re: refRange with non copyable struct

2017-04-17 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 17 April 2017 at 19:00:44 UTC, Jonathan M Davis wrote:

Because otherwise, it's not acting like a reference to the 
original range, which is the whole point of RefRange. The 
correct solution would probably be to @disable opAssign in the 
case where the original range can't be overwritten by another 
range.


This doesn't look quite right. References in D are rebindable. 
That is, assigning a reference to a reference does not copy 
referenced object, only the reference itself.

It seems that RefRange is trying to impersonate a C++ reference.


Re: refRange with non copyable struct

2017-04-17 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, April 17, 2017 18:45:46 Jerry via Digitalmars-d-learn wrote:
> On Monday, 17 April 2017 at 18:07:36 UTC, Jonathan M Davis wrote:
> > In this particular case, it looks like the main problem is
> > RefRange's opAssign. For it to work, the type needs to be
> > copyable. It might be reasonable for RefRange to be enhanced so
> > that it doesn't compile in opAssign if the range isn't
> > copyable, but I'd have to study RefRange in depth to know what
> > the exact consequences of that would be, since it's been quite
> > a while since I did anything with it. My guess is that such a
> > change would be reasonable, but I don't know without studying
> > it.
> >
> > - Jonathan M Davis
>
> I took a look on RefRange and the reasoning is clearly explained
> in the docs like this:
>
> This does not assign the pointer of $(D rhs) to this $(D
> RefRange).
> Rather it assigns the range pointed to by $(D rhs) to the range
> pointed
> to by this $(D RefRange). This is because $(I any) operation on a
> RefRange) is the same is if it occurred to the original range. The
> exception is when a $(D RefRange) is assigned $(D null) either
> or because $(D rhs) is $(D null). In that case, $(D RefRange)
> longer refers to the original range but is $(D null).
>
>
>
> But what I do not understand is why this is important.

Because otherwise, it's not acting like a reference to the original range,
which is the whole point of RefRange. The correct solution would probably be
to @disable opAssign in the case where the original range can't be
overwritten by another range.

- Jonathan M Davis



Re: refRange with non copyable struct

2017-04-17 Thread Jerry via Digitalmars-d-learn

On Monday, 17 April 2017 at 18:07:36 UTC, Jonathan M Davis wrote:
In this particular case, it looks like the main problem is 
RefRange's opAssign. For it to work, the type needs to be 
copyable. It might be reasonable for RefRange to be enhanced so 
that it doesn't compile in opAssign if the range isn't 
copyable, but I'd have to study RefRange in depth to know what 
the exact consequences of that would be, since it's been quite 
a while since I did anything with it. My guess is that such a 
change would be reasonable, but I don't know without studying 
it.


- Jonathan M Davis


I took a look on RefRange and the reasoning is clearly explained 
in the docs like this:


This does not assign the pointer of $(D rhs) to this $(D 
RefRange).
Rather it assigns the range pointed to by $(D rhs) to the range 
pointed

to by this $(D RefRange). This is because $(I any) operation on a
RefRange) is the same is if it occurred to the original range. The
exception is when a $(D RefRange) is assigned $(D null) either
or because $(D rhs) is $(D null). In that case, $(D RefRange)
longer refers to the original range but is $(D null).



But what I do not understand is why this is important.


Re: refRange with non copyable struct

2017-04-17 Thread Jerry via Digitalmars-d-learn

On Monday, 17 April 2017 at 18:07:36 UTC, Jonathan M Davis wrote:

Non-copyable types tend to wreak havoc with things
- Jonathan M Davis


Basicly what I use this for is to combine RAII with ranges.
Which I find quite useful when doing DB queries and the data is 
lazily fetched
since this allows me to guarantee that the query is "closed" and 
another query can take place.




Re: refRange with non copyable struct

2017-04-17 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, April 17, 2017 17:23:32 Jerry via Digitalmars-d-learn wrote:
> Hello guys, so I wanted to have a noncopyable range on the stack.
> So my thoughts was to make it non copyable and use refRange
> whenever I want to use it with map and others.
>
> But I got a compiler warning when doing so like this:
>
> import std.range;
>
> void main() {
>   NonCopyable v;
>
>   refRange();
> }
>
> struct NonCopyable
> {
>   @disable this(this);
>
>   int data;
>
>   enum empty = false;
>   void popFront() {}
>   int front() { return data; }
> }
>
>
>
>
>
> With the error message:
>
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\package.d(8941):
> Error: struct reproduction.NonCopyable is not copyable because it
> is annotated with @disable
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\package.d(8982):
> Error: mutable method reproduction.NonCopyable.front is not
> callable using a const object
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\package.d(9649):
> Error: template instance std.range.RefRange!(NonCopyable) error
> instantiating
> reproduction.d(6):instantiated from here:
> refRange!(NonCopyable)
>
>
>
>
> Is there any workaround?
> Is this a bug?

Well, I don't think that much range-based code in general is going to work
with a disabled postblit constructor, and it's not something that's
generally tested for unless someone is specifically trying to use such a
type with a specific piece of code. Non-copyable types tend to wreak havoc
with things - not that they shouldn't necessarily work, but most stuff tends
to assume that types are copyable, and supporting non-copyable often
complicates things quite a bit. Most of Phobos simply hasn't been tested
with non-copyable types even if the functionality in question should
arguably work with them.

In this particular case, it looks like the main problem is RefRange's
opAssign. For it to work, the type needs to be copyable. It might be
reasonable for RefRange to be enhanced so that it doesn't compile in
opAssign if the range isn't copyable, but I'd have to study RefRange in
depth to know what the exact consequences of that would be, since it's been
quite a while since I did anything with it. My guess is that such a change
would be reasonable, but I don't know without studying it.

- Jonathan M Davis



refRange with non copyable struct

2017-04-17 Thread Jerry via Digitalmars-d-learn

Hello guys, so I wanted to have a noncopyable range on the stack.
So my thoughts was to make it non copyable and use refRange 
whenever I want to use it with map and others.


But I got a compiler warning when doing so like this:

import std.range;

void main() {
NonCopyable v;

refRange();
}

struct NonCopyable
{
@disable this(this);

int data;

enum empty = false;
void popFront() {}
int front() { return data; }
}





With the error message:

C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\package.d(8941): 
Error: struct reproduction.NonCopyable is not copyable because it 
is annotated with @disable
C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\package.d(8982): 
Error: mutable method reproduction.NonCopyable.front is not 
callable using a const object
C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\package.d(9649): 
Error: template instance std.range.RefRange!(NonCopyable) error 
instantiating
reproduction.d(6):instantiated from here: 
refRange!(NonCopyable)





Is there any workaround?
Is this a bug?


[Issue 16534] RefRange should define opDollar if it defines length

2016-10-01 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16534

--- Comment #4 from github-bugzi...@puremagic.com ---
Commits pushed to stable at https://github.com/dlang/phobos

https://github.com/dlang/phobos/commit/8dd953827c9b211c76985b48a9409c2ba0fcfd19
Fix issue 16534 - RefRange should define opDollar if it defines length

https://github.com/dlang/phobos/commit/8c16746cc8a54ba1f9222f62b408c590e3d2fd69
Merge pull request #4817 from
ZombineDev/fix-16534-refrange-should-define-dollar-if-possible

--


[Issue 16534] RefRange should define opDollar if it defines length

2016-09-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16534

--- Comment #3 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/dlang/phobos

https://github.com/dlang/phobos/commit/8dd953827c9b211c76985b48a9409c2ba0fcfd19
Fix issue 16534 - RefRange should define opDollar if it defines length

https://github.com/dlang/phobos/commit/8c16746cc8a54ba1f9222f62b408c590e3d2fd69
Merge pull request #4817 from
ZombineDev/fix-16534-refrange-should-define-dollar-if-possible

Fix issue 16534 - RefRange should define opDollar if it defines length

--


[Issue 16534] RefRange should define opDollar if it defines length

2016-09-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16534

github-bugzi...@puremagic.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--


[Issue 16534] RefRange should define opDollar if it defines length

2016-09-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16534

ZombineDev  changed:

   What|Removed |Added

   Keywords||pull
 CC||petar.p.ki...@gmail.com

--- Comment #2 from ZombineDev  ---
PR: https://github.com/dlang/phobos/pull/4817

--


[Issue 16534] RefRange should define opDollar if it defines length

2016-09-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16534

--- Comment #1 from Andrei Alexandrescu  ---
See also: http://forum.dlang.org/post/ns66l7$1sp5$1...@digitalmars.com

--


[Issue 16534] New: RefRange should define opDollar if it defines length

2016-09-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16534

  Issue ID: 16534
   Summary: RefRange should define opDollar if it defines length
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: and...@erdani.com

That's pretty much it.

--


Re: refRange and @disable this(this);

2016-09-15 Thread Jacob Carlborg via Digitalmars-d

On 2016-09-14 14:39, Jerry wrote:

I got a range which disables copy construction and I want to loop the
range within another loop using the same range.
So I thought I can mark the struct range with @disable this(this) and
then use refRange to initialize the loop.

So with something like this:

void main()
{
auto valueRange = FooRange("123");
foreach(ch; refRange())
writeln(ch);
}


struct FooRange {
@disable this();
@disable this(this);
this(string str) {
this.str = str;
}

@property bool empty() { return str.empty; }
@property dchar front() { return str.front; }
void popFront() { str.popFront; }

private:
string str;
}


But I get compile time errors messages saying:
std/range/package.d(8155,23): Error: struct app.FooRange is not copyable
because it is annotated with @disable

It feels strange that refRange ever want to copy.
Bug or feature?


As a workaround you can take the address of the range and use 
std.algorithm.each:


void main()
{
auto valueRange = FooRange("123");
().each!(ch => writeln(ch));
}

With a convenience function:

T* ptr(ref T t){ return  }

void main()
{
auto valueRange = FooRange("123");
valueRange.ptr.each!(ch => writeln(ch));
}

--
/Jacob Carlborg


Re: refRange and @disable this(this);

2016-09-14 Thread Mathias Lang via Digitalmars-d
You should be able to work around this by using `for` loop instead of
`foreach`.
IMO that's a design bug in `foreach`:
https://issues.dlang.org/show_bug.cgi?id=15413

2016-09-14 14:39 GMT+02:00 Jerry via Digitalmars-d <
digitalmars-d@puremagic.com>:

> I got a range which disables copy construction and I want to loop the
> range within another loop using the same range.
> So I thought I can mark the struct range with @disable this(this) and then
> use refRange to initialize the loop.
>
> So with something like this:
>
> void main()
> {
> auto valueRange = FooRange("123");
> foreach(ch; refRange())
> writeln(ch);
> }
>
>
> struct FooRange {
> @disable this();
> @disable this(this);
> this(string str) {
> this.str = str;
> }
>
> @property bool empty() { return str.empty; }
> @property dchar front() { return str.front; }
> void popFront() { str.popFront; }
>
> private:
> string str;
> }
>
>
> But I get compile time errors messages saying:
> std/range/package.d(8155,23): Error: struct app.FooRange is not copyable
> because it is annotated with @disable
>
> It feels strange that refRange ever want to copy.
> Bug or feature?
>
>


Re: refRange and @disable this(this);

2016-09-14 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, September 14, 2016 12:39:16 Jerry via Digitalmars-d wrote:
> I got a range which disables copy construction and I want to loop
> the range within another loop using the same range.
> So I thought I can mark the struct range with @disable this(this)
> and then use refRange to initialize the loop.
>
> So with something like this:
>
> void main()
> {
>   auto valueRange = FooRange("123");
>   foreach(ch; refRange())
>   writeln(ch);
> }
>
>
> struct FooRange {
>   @disable this();
>   @disable this(this);
>   this(string str) {
>   this.str = str;
>   }
>
>   @property bool empty() { return str.empty; }
>   @property dchar front() { return str.front; }
>   void popFront() { str.popFront; }
>
> private:
>   string str;
> }
>
>
> But I get compile time errors messages saying:
> std/range/package.d(8155,23): Error: struct app.FooRange is not
> copyable because it is annotated with @disable
>
> It feels strange that refRange ever want to copy.
> Bug or feature?

It's opAssign does a copy. The rationale is given in its documentation:

http://dlang.org/phobos/std_range.html#.RefRange.opAssign

The result of that is that the range you give it needs to be copyable. But
the reality of the matter is that ranges in general expect to be copyable,
and range-based code is going to have a tendency to fall flat on its face if
you try to define a range that's non-copyable. I'm actually kind of
surprised that such a range passes isInputRange given that it tests this
line:

R r = R.init;

But I guess that it works, because you didn't explicitly disable opAssign
(though at least sometimes, disabling the postblit constructor seems to
disable opAssign from what I recall).

If want to guarantee that a range's state is never copied, and you're
creating a range specifically for this, you might as well just make it a
class and force it to have reference semantics. RefRange was intended for
cases where you have a range that works normally, but you need to pass it to
some code and have the the state of the range be updated rather than having
a copy updated. It wasn't intended that it be used for a range that you
wanted to always be a reference type, since if you want that, you can just
declare a range that's a reference type.

- Jonathan M Davis



Re: refRange and @disable this(this);

2016-09-14 Thread Jerry via Digitalmars-d

On Wednesday, 14 September 2016 at 12:39:16 UTC, Jerry wrote:

It feels strange that refRange ever want to copy.
Bug or feature?


Or more specificly, shouldn't save only be defined if the range 
defines it instead of using copy? Which is presume is the problem.


refRange and @disable this(this);

2016-09-14 Thread Jerry via Digitalmars-d
I got a range which disables copy construction and I want to loop 
the range within another loop using the same range.
So I thought I can mark the struct range with @disable this(this) 
and then use refRange to initialize the loop.


So with something like this:

void main()
{   
auto valueRange = FooRange("123");
foreach(ch; refRange())
writeln(ch);
}


struct FooRange {
@disable this();
@disable this(this);
this(string str) {
this.str = str;
}

@property bool empty() { return str.empty; }
@property dchar front() { return str.front; }
void popFront() { str.popFront; }

private:
string str;
}


But I get compile time errors messages saying:
std/range/package.d(8155,23): Error: struct app.FooRange is not 
copyable because it is annotated with @disable


It feels strange that refRange ever want to copy.
Bug or feature?



[Issue 10885] [std.range] refRange is missing from module description tables

2013-08-26 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10885



--- Comment #2 from github-bugzi...@puremagic.com 2013-08-26 03:38:13 PDT ---
Commit pushed to master at https://github.com/D-Programming-Language/phobos

https://github.com/D-Programming-Language/phobos/commit/f3e8844b3d0d00def99d7c9118497a0b699c6df1
Merge pull request #1522 from quickfur/issue10885

Add RefRange to ddoc overview (issue 10885)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10885] [std.range] refRange is missing from module description tables

2013-08-26 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10885


monarchdo...@gmail.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||monarchdo...@gmail.com
 Resolution||FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10885] [std.range] refRange is missing from module description tables

2013-08-25 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10885


hst...@quickfur.ath.cx changed:

   What|Removed |Added

   Keywords||pull
 CC||hst...@quickfur.ath.cx


--- Comment #1 from hst...@quickfur.ath.cx 2013-08-25 14:10:15 PDT ---
https://github.com/D-Programming-Language/phobos/pull/1522

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10885] New: [std.range] refRange is missing from module description tables

2013-08-24 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10885

   Summary: [std.range] refRange is missing from module
description tables
   Product: D
   Version: D2
  Platform: All
OS/Version: All
Status: NEW
  Severity: minor
  Priority: P2
 Component: websites
AssignedTo: nob...@puremagic.com
ReportedBy: paolo.inverni...@gmail.com


--- Comment #0 from Paolo Invernizzi paolo.inverni...@gmail.com 2013-08-24 
14:11:01 PDT ---
The link is actually present in the 'Jump To' list, but not in the tables in
the top description of the module content.

This is a problem as it's very easy to skip its presence, as a person is
focused in exploring the module functionality reading the module description,
while the refRange and companions are at the very bottom of the web page right
now.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


RefRange

2012-08-26 Thread David
It's a RefRange, but not completly ... Can somebody explain me that 
behaviour?


http://dpaste.dzfl.pl/643de2a3


Re: RefRange

2012-08-26 Thread Ali Çehreli

On 08/26/2012 08:41 AM, David wrote:

It's a RefRange, but not completly ... Can somebody explain me that
behaviour?

http://dpaste.dzfl.pl/643de2a3


According to its documentation, RefRange works differently whether the 
original range is a ForwardRange or not:


  http://dlang.org/phobos/std_range.html#refRange

I have made TestRange a ForwardRange but then I had to comment out two 
lines of your program. Does it work according to your expectations with 
this change?


import std.stdio;
import std.range;

struct TestRange {
float[] x = [0, 1, 2, 3, 4, 5];

@property bool empty() {
return x.length == 0;
}

@property ref float front() {
return x[0];
}

void popFront() {
//writefln(before: %s, x);
x = x[1..$];
//x.popFront();
//writefln(after: %s, x);
}

TestRange save() @property {
return TestRange(x);
}
}



void main() {
static assert(isForwardRange!TestRange);

TestRange r = TestRange();
auto rr = refRange(r);

//foreach(element; rr) {}

//writefln(Original range: %s, r.x);
//writefln(RefRange: %s, rr.x);

writefln(%s - %s, r.x.ptr, r.x.ptr);

rr.popFront();

writefln(%s - %s, r.x.ptr, r.x.ptr);
writefln(Original range: %s, r.x);
// We can't expect the RefRange to have the members of the original 
range

// writefln(RefRange: %s, rr.x);

r.popFront();

writefln(%s - %s, r.x.ptr, r.x.ptr);
writefln(Original range: %s, r.x);
// We can't expect the RefRange to have the members of the original 
range

// writefln(RefRange: %s, rr.x);
}

Ali


Re: RefRange

2012-08-26 Thread Jonathan M Davis
On Sunday, August 26, 2012 17:41:45 David wrote:
 It's a RefRange, but not completly ... Can somebody explain me that
 behaviour?

 http://dpaste.dzfl.pl/643de2a3

refRange simply returns the original range if it's an input range rather than 
a forward range, since normally, when you have an input range, it isn't a 
value type, and there's no way to copy it, so operating on one reference of it 
is already the same as operating on all of them, making RefRange pointless.

However, you've done the odd thing of declaring a value type input range. I 
don't know why that would ever be done except through ignorance of how ranges 
work. So, refRange is actually returning a copy in your case, which is why 
you're having problems.

And by the way, the only reason that rr.x works is because refRange is 
returning a copy rather than a RefRange!TestRange.

- Jonathan M Davis


Re: RefRange

2012-08-26 Thread Jonathan M Davis
On Sunday, August 26, 2012 10:17:13 Jonathan M Davis wrote:
 On Sunday, August 26, 2012 17:41:45 David wrote:
  It's a RefRange, but not completly ... Can somebody explain me that
  behaviour?
  
  http://dpaste.dzfl.pl/643de2a3
 
 refRange simply returns the original range if it's an input range rather
 than a forward range, since normally, when you have an input range, it
 isn't a value type, and there's no way to copy it, so operating on one
 reference of it is already the same as operating on all of them, making
 RefRange pointless.
 
 However, you've done the odd thing of declaring a value type input range. I
 don't know why that would ever be done except through ignorance of how
 ranges work. So, refRange is actually returning a copy in your case, which
 is why you're having problems.

Though the fact that you ran into this issue may indicate that having refRange 
return the original if it isn't a forward range was a bad decision. I don't 
know. In the normal case, it's definitely better, because it avoids an 
unnecessary wrapper, but obviously, people can make mistakes. You should still 
be able use RefRange with an input range though, as long as you use it 
directly.

auto wrapped = RefRange!TestRange(orig);

But it would be better IMHO to just fix it so that your range is a forward 
range, since there's no reason for it not to be.

- Jonathan M Davis


Re: RefRange

2012-08-26 Thread David

Am 26.08.2012 20:07, schrieb Jonathan M Davis:

On Sunday, August 26, 2012 10:17:13 Jonathan M Davis wrote:

On Sunday, August 26, 2012 17:41:45 David wrote:

It's a RefRange, but not completly ... Can somebody explain me that
behaviour?

http://dpaste.dzfl.pl/643de2a3


refRange simply returns the original range if it's an input range rather
than a forward range, since normally, when you have an input range, it
isn't a value type, and there's no way to copy it, so operating on one
reference of it is already the same as operating on all of them, making
RefRange pointless.

However, you've done the odd thing of declaring a value type input range. I
don't know why that would ever be done except through ignorance of how
ranges work. So, refRange is actually returning a copy in your case, which
is why you're having problems.


Though the fact that you ran into this issue may indicate that having refRange
return the original if it isn't a forward range was a bad decision. I don't
know. In the normal case, it's definitely better, because it avoids an
unnecessary wrapper, but obviously, people can make mistakes. You should still
be able use RefRange with an input range though, as long as you use it
directly.

auto wrapped = RefRange!TestRange(orig);

But it would be better IMHO to just fix it so that your range is a forward
range, since there's no reason for it not to be.

- Jonathan M Davis



Ranges died another time for me. This refRange copy thingy cost me lots 
of time, then I tried to implement a .save method, which uhm, just 
didn't work together with RefRange (isForwardRange!T succeeded, but 
isForwardRange!(RefRange!T) failed).


Anyways, thanks for your explanations!


Re: RefRange

2012-08-26 Thread David

Am 26.08.2012 18:06, schrieb Ali Çehreli:

On 08/26/2012 08:41 AM, David wrote:

It's a RefRange, but not completly ... Can somebody explain me that
behaviour?

http://dpaste.dzfl.pl/643de2a3


According to its documentation, RefRange works differently whether the
original range is a ForwardRange or not:

   http://dlang.org/phobos/std_range.html#refRange

I have made TestRange a ForwardRange but then I had to comment out two
lines of your program. Does it work according to your expectations with
this change?

import std.stdio;
import std.range;

struct TestRange {
 float[] x = [0, 1, 2, 3, 4, 5];

 @property bool empty() {
 return x.length == 0;
 }

 @property ref float front() {
 return x[0];
 }

 void popFront() {
 //writefln(before: %s, x);
 x = x[1..$];
 //x.popFront();
 //writefln(after: %s, x);
 }

 TestRange save() @property {
 return TestRange(x);
 }
}



void main() {
 static assert(isForwardRange!TestRange);

 TestRange r = TestRange();
 auto rr = refRange(r);

 //foreach(element; rr) {}

 //writefln(Original range: %s, r.x);
 //writefln(RefRange: %s, rr.x);

 writefln(%s - %s, r.x.ptr, r.x.ptr);

 rr.popFront();

 writefln(%s - %s, r.x.ptr, r.x.ptr);
 writefln(Original range: %s, r.x);
 // We can't expect the RefRange to have the members of the original
range
 // writefln(RefRange: %s, rr.x);

 r.popFront();

 writefln(%s - %s, r.x.ptr, r.x.ptr);
 writefln(Original range: %s, r.x);
 // We can't expect the RefRange to have the members of the original
range
 // writefln(RefRange: %s, rr.x);
}

Ali


Yes, that does it, but .save doesn't play well with RefRange (a static 
assert inside RefRange fails, telling that the produced RefRange-Type is 
not a ForwardRange).


Re: RefRange

2012-08-26 Thread Ali Çehreli

On 08/26/2012 02:21 PM, David wrote:

 I tried to implement a .save method, which uhm, just
 didn't work together with RefRange (isForwardRange!T succeeded, but
 isForwardRange!(RefRange!T) failed).

What version of dmd? What is the code?

When I add the following lines to the beginning of main() of the program 
that I have used in my other post, they both pass:


static assert(isForwardRange!TestRange);
static assert(isForwardRange!(RefRange!TestRange));

Ali



Re: RefRange

2012-08-26 Thread David

Am 26.08.2012 23:33, schrieb Ali Çehreli:

On 08/26/2012 02:21 PM, David wrote:

  I tried to implement a .save method, which uhm, just
  didn't work together with RefRange (isForwardRange!T succeeded, but
  isForwardRange!(RefRange!T) failed).

What version of dmd? What is the code?

When I add the following lines to the beginning of main() of the program
that I have used in my other post, they both pass:

 static assert(isForwardRange!TestRange);
 static assert(isForwardRange!(RefRange!TestRange));

Ali



DMD 2.059 and: 
https://github.com/Dav1dde/BraLa/blob/7440688038bfd50a06fd9a49b8e9b6d08c7b4c28/brala/utils/queue.d


But I don't care anylonger, I rewrote the whole Queue class (now it's a 
real queue, e.g. you can wait until all items are used up, with 
core.sync.condtion), I also don't feel like wasting more time in ranges, 
when I don't need them.


Re: RefRange

2012-06-14 Thread Lars T. Kyllingstad

On Thursday, 14 June 2012 at 05:45:50 UTC, Jonathan M Davis wrote:

On Thursday, June 14, 2012 07:35:35 Lars T. Kyllingstad wrote:
However, someone pointed out here earlier that, since D uses 
the

dot operator for pointer dereferencing, a pointer to a range is
also a range.  It just isn't recognised as such by foreach.  So
if we could just fix foreach, and maybe add functions providing
range primitives for T[]* to std.array, I don't think we need a
separate RefRange.  Just take the address of the range when you
want to ensure it gets consumed.


I don't think that that would work with save or opSlice though. 
Granted, save
and opSlice _can_ make it so that the range isn't consumed like 
you'd like,
depending on how the function that you're passing it to is 
implemented, but
having RefRange implement save and opSlice is still useful, and 
is actually
necessary if you want it to work as RandomAccessRange and the 
like (since all
of the more complex ranges are forward ranges). So, if that 
won't work with a
pointer (and I don't think that it will, since the type would 
be completely

wrong), then you'd still need a type like RefRange.


Ah, that's true, of course.  Indexing and slicing would be a 
disaster if one tried to do it with a pointer to a range. :)  
Then we should definitely have a RefRange.  I actually suggested 
the very same thing on the Phobos ML myself once, but Andrei 
argued it would be better to define a more general Ref type, 
which works with all kinds of types, and not just ranges.  
Personally, I would be happy with something just for ranges.


-Lars



RefRange

2012-06-13 Thread Jonathan M Davis
I ran into a situation where I needed a forward range which was not a 
reference type to be consumed by a range-based function. Input ranges and 
reference type forward ranges are automatically and unavoidably consumed by 
range-based functions (assuming that save isn't called on them before the 
function starts consuming them), but that doesn't happen for either value type 
ranges or arrays. Hence my wrapper type (called RefRange). The code is here:

http://codepad.org/nNB4mAdN

I was wondering what other people's take on it was and whether I missed 
something which makes it a bad idea. Essentially, it's a range with a pointer 
to the original range so that any function calls on the wrapper affect the 
original range (and vice versa).

Assuming that no one pokes a major hole in it, and others think that it's a 
worthwhile addition, I'll create a pull request for it to be added to 
std.range. But I'd like other people's feedback on it first.

- Jonathan M Davis


Re: RefRange

2012-06-13 Thread Lars T. Kyllingstad

On Thursday, 14 June 2012 at 04:14:02 UTC, Jonathan M Davis wrote:
I ran into a situation where I needed a forward range which was 
not a
reference type to be consumed by a range-based function. Input 
ranges and
reference type forward ranges are automatically and unavoidably 
consumed by
range-based functions (assuming that save isn't called on them 
before the
function starts consuming them), but that doesn't happen for 
either value type
ranges or arrays. Hence my wrapper type (called RefRange). The 
code is here:


http://codepad.org/nNB4mAdN

I was wondering what other people's take on it was and whether 
I missed
something which makes it a bad idea. Essentially, it's a range 
with a pointer
to the original range so that any function calls on the wrapper 
affect the

original range (and vice versa).

Assuming that no one pokes a major hole in it, and others think 
that it's a
worthwhile addition, I'll create a pull request for it to be 
added to

std.range. But I'd like other people's feedback on it first.


It is definitely a good idea.  Basically, it provides the 
opposite guarantee of save().  If you're going to use the range 
once and then throw it away, and therefore don't care whether it 
is consumed or not, just use it directly.  If you want to ensure 
it does not get consumed, use a copy obtained through save().  If 
you want to ensure it *does* get consumed, use a reference to it.


However, someone pointed out here earlier that, since D uses the 
dot operator for pointer dereferencing, a pointer to a range is 
also a range.  It just isn't recognised as such by foreach.  So 
if we could just fix foreach, and maybe add functions providing 
range primitives for T[]* to std.array, I don't think we need a 
separate RefRange.  Just take the address of the range when you 
want to ensure it gets consumed.


-Lars


Re: RefRange

2012-06-13 Thread Jonathan M Davis
On Thursday, June 14, 2012 07:35:35 Lars T. Kyllingstad wrote:
 On Thursday, 14 June 2012 at 04:14:02 UTC, Jonathan M Davis wrote:
  I ran into a situation where I needed a forward range which was
  not a
  reference type to be consumed by a range-based function. Input
  ranges and
  reference type forward ranges are automatically and unavoidably
  consumed by
  range-based functions (assuming that save isn't called on them
  before the
  function starts consuming them), but that doesn't happen for
  either value type
  ranges or arrays. Hence my wrapper type (called RefRange). The
  code is here:
  
  http://codepad.org/nNB4mAdN
  
  I was wondering what other people's take on it was and whether
  I missed
  something which makes it a bad idea. Essentially, it's a range
  with a pointer
  to the original range so that any function calls on the wrapper
  affect the
  original range (and vice versa).
  
  Assuming that no one pokes a major hole in it, and others think
  that it's a
  worthwhile addition, I'll create a pull request for it to be
  added to
  std.range. But I'd like other people's feedback on it first.
 
 It is definitely a good idea.  Basically, it provides the
 opposite guarantee of save().  If you're going to use the range
 once and then throw it away, and therefore don't care whether it
 is consumed or not, just use it directly.  If you want to ensure
 it does not get consumed, use a copy obtained through save().  If
 you want to ensure it *does* get consumed, use a reference to it.
 
 However, someone pointed out here earlier that, since D uses the
 dot operator for pointer dereferencing, a pointer to a range is
 also a range.  It just isn't recognised as such by foreach.  So
 if we could just fix foreach, and maybe add functions providing
 range primitives for T[]* to std.array, I don't think we need a
 separate RefRange.  Just take the address of the range when you
 want to ensure it gets consumed.

I don't think that that would work with save or opSlice though. Granted, save 
and opSlice _can_ make it so that the range isn't consumed like you'd like, 
depending on how the function that you're passing it to is implemented, but 
having RefRange implement save and opSlice is still useful, and is actually 
necessary if you want it to work as RandomAccessRange and the like (since all 
of the more complex ranges are forward ranges). So, if that won't work with a 
pointer (and I don't think that it will, since the type would be completely 
wrong), then you'd still need a type like RefRange.

- Jonathan M Davis