std.range.ref_range
- multiple declarations
- Function refRange
- Struct RefRange
Function refRange
Helper function for constructing a RefRange
.
If the given range
is a class type (and thus is already a reference type),
then the original range
is returned rather than a RefRange
.
Prototypes
auto refRange(R)( R* range ) if (isInputRange!R && !is(R == class)); auto refRange(R)( R* range ) if (isInputRange!R && is(R == class));
Example
import std.algorithm : map, joiner, group, until; // fix for std.algorithm auto r = map!(x => 0)([1]); chain(r, r); zip(r, r); roundRobin(r, r); struct NRAR { typeof(r) input; @property empty() { return input.empty; } @property front() { return input.front; } void popFront() { input.popFront(); } @property save() { return NRAR(input.save); } } auto n1 = NRAR(r); cycle(n1); // non random access range version assumeSorted(r); // fix for std.range joiner([r], [9]); struct NRAR2 { NRAR input; @property empty() { return true; } @property front() { return input; } void popFront() { } @property save() { return NRAR2(input.save); } } auto n2 = NRAR2(n1); joiner(n2); group(r); until(r, 7); static void foo(R)(R r) { until!(x => x > 7)(r); } foo(r);
Struct RefRange
Wrapper which effectively makes it possible to pass a range by reference.
Both the original range and the RefRange
will always have the exact same
elements. Any operation done on one will affect the other. So, for instance,
if it's passed to a function which would implicitly copy the original range
if it were passed to it, the original range is not copied but is
consumed as if it were a reference type.
Note that save
works as normal and operates on a new range, so if
save
is ever called on the RefRange
, then no operations on the saved
range will affect the original.
Constructors
Name | Description |
---|---|
this
|
Properties
Name | Type | Description |
---|---|---|
ptr
[get]
|
inout(R*) |
A pointer to the wrapped range. |
Methods
Name | Description |
---|---|
opAssign
|
This does not assign the pointer of to this .
Rather it assigns the range pointed to by to the range pointed
to by this . This is because any operation on a
is the same is if it occurred to the original range. The
one exception is when a is assigned null either
directly or because is null . In that case,
no longer refers to the original range but is null .
|
opAssign
|
|
popFront
|
Example
Basic Example
import std.algorithm; ubyte[] buffer = [1, 9, 45, 12, 22]; auto found1 = find(buffer, 45); assert(found1 == [45, 12, 22]); assert(buffer == [1, 9, 45, 12, 22]); auto wrapped1 = refRange(&buffer); auto found2 = find(wrapped1, 45); assert(*found2.ptr == [45, 12, 22]); assert(buffer == [45, 12, 22]); auto found3 = find(wrapped1.save, 22); assert(*found3.ptr == [22]); assert(buffer == [45, 12, 22]); string str = "hello world"; auto wrappedStr = refRange(&str); assert(str.front == 'h'); str.popFrontN(5); assert(str == " world"); assert(wrappedStr.front == ' '); assert(*wrappedStr.ptr == " world");
Example
opAssign
Example.
ubyte[] buffer1 = [1, 2, 3, 4, 5]; ubyte[] buffer2 = [6, 7, 8, 9, 10]; auto wrapped1 = refRange(&buffer1); auto wrapped2 = refRange(&buffer2); assert(wrapped1.ptr is &buffer1); assert(wrapped2.ptr is &buffer2); assert(wrapped1.ptr !is wrapped2.ptr); assert(buffer1 != buffer2); wrapped1 = wrapped2; //Everything points to the same stuff as before. assert(wrapped1.ptr is &buffer1); assert(wrapped2.ptr is &buffer2); assert(wrapped1.ptr !is wrapped2.ptr); //But buffer1 has changed due to the assignment. assert(buffer1 == [6, 7, 8, 9, 10]); assert(buffer2 == [6, 7, 8, 9, 10]); buffer2 = [11, 12, 13, 14, 15]; //Everything points to the same stuff as before. assert(wrapped1.ptr is &buffer1); assert(wrapped2.ptr is &buffer2); assert(wrapped1.ptr !is wrapped2.ptr); //But buffer2 has changed due to the assignment. assert(buffer1 == [6, 7, 8, 9, 10]); assert(buffer2 == [11, 12, 13, 14, 15]); wrapped2 = null; //The pointer changed for wrapped2 but not wrapped1. assert(wrapped1.ptr is &buffer1); assert(wrapped2.ptr is null); assert(wrapped1.ptr !is wrapped2.ptr); //buffer2 is not affected by the assignment. assert(buffer1 == [6, 7, 8, 9, 10]); assert(buffer2 == [11, 12, 13, 14, 15]);
Authors
Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.