std.typecons.Rebindable/rebindable
- multiple declarations
Function rebindable
This function simply returns the Rebindable
object passed in. It's useful
in generic programming cases when a given object may be either a regular
class
or a Rebindable
.
Parameters
Name | Description |
---|---|
obj | An instance of Rebindable!T. |
Returns
obj
without any modification.
Example
class C
{
int payload;
this(int p) { payload = p; }
}
const c = new C(1);
auto c2 = c .rebindable;
writeln(c2 .payload); // 1
// passing Rebindable to rebindable
c2 = c2 .rebindable;
writeln(c2 .payload); // 1
Function rebindable
Convenience function for creating a Rebindable
using automatic type
inference.
Rebindable!T rebindable(T)
(
T obj
)
if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T);
Rebindable!T rebindable(T)
(
T value
)
if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T && !is(T : Rebindable!U, U));
Parameters
Name | Description |
---|---|
obj | A reference to a value to initialize the Rebindable with. |
Returns
A newly constructed Rebindable
initialized with the given reference.
Example
class C
{
int payload;
this(int p) { payload = p; }
}
const c = new C(1);
auto c2 = c .rebindable;
writeln(c2 .payload); // 1
// passing Rebindable to rebindable
c2 = c2 .rebindable;
c2 = new C(2);
writeln(c2 .payload); // 2
const c3 = c2 .get;
writeln(c3 .payload); // 2
Example
immutable struct S
{
int[] array;
}
auto s1 = [3] .idup .rebindable;
s1 = [4] .idup .rebindable;
writeln(s1); // [4]
Alias/Struct Rebindable
Rebindable!(T)
is a simple, efficient wrapper that behaves just
like an object of type T
, except that you can reassign it to
refer to another object. For completeness, Rebindable!(T)
aliases
itself away to T
if T
is a non-const object type.
struct Rebindable(T)
if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T);
You may want to use Rebindable
when you want to have mutable
storage referring to const
objects, for example an array of
references that must be sorted in place. Rebindable
does not
break the soundness of D's type system and does not incur any of the
risks usually associated with cast
.
Alias Rebindable
Struct Rebindable
Constructors
Name | Description |
---|---|
this
(value)
|
Constructs a Rebindable from a given value.
|
Properties
Name | Type | Description |
---|---|---|
get [get]
|
T | Returns the value currently stored in the Rebindable .
|
Methods
Name | Description |
---|---|
opAssign
(value)
|
Overwrites the currently stored value with value .
|
Parameters
Name | Description |
---|---|
T | Any type. |
Example
Regular const
object references cannot be reassigned.
class Widget { int x; int y() @safe const { return x; } }
const a = new Widget;
// Fine
a .y();
// error! can't modify const a
// a.x = 5;
// error! can't modify const a
// a = new Widget;
Example
However, Rebindable!(Widget)
does allow reassignment,
while otherwise behaving exactly like a const Widget
.
class Widget { int x; int y() const @safe { return x; } }
auto a = Rebindable!(const Widget)(new Widget);
// Fine
a .y();
// error! can't modify const a
// a.x = 5;
// Fine
a = new Widget;
Example
Using Rebindable in a generic algorithm:
import std .range .primitives : front, popFront;
// simple version of std.algorithm.searching.maxElement
typeof(R .init .front) maxElement(R)(R r)
{
auto max = rebindable(r .front);
r .popFront;
foreach (e; r)
if (e > max)
max = e; // Rebindable allows const-correct reassignment
return max;
}
struct S
{
char[] arr;
alias arr this; // for comparison
}
// can't convert to mutable
const S cs;
static assert(!__traits(compiles, { S s = cs; }));
alias CS = const S;
CS[] arr = [CS("harp"), CS("apple"), CS("pot")];
CS ms = maxElement(arr);
writeln(ms .arr); // "pot"
Example
static struct S
{
int* ptr;
}
S s = S(new int);
const cs = s;
// Can't assign s.ptr to cs.ptr
static assert(!__traits(compiles, {s = cs;}));
Rebindable!(const S) rs = s;
assert(rs .ptr is s .ptr);
// rs.ptr is const
static assert(!__traits(compiles, {rs .ptr = null;}));
// Can't assign s.ptr to rs.ptr
static assert(!__traits(compiles, {s = rs;}));
const S cs2 = rs;
// Rebind rs
rs = cs2;
rs = S();
assert(rs .ptr is null);
Authors
Andrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara