Creating ranges over mutable, const, or immutable data structures.
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun May 25 01:08:38 PDT 2014
On 05/24/2014 10:02 AM, w0rp wrote:
> Create a mutable KeyRange over a map which forwards on the right
> constness for the key type, so the following must be true.
>
> HashMap!(K, V).keys.front -> K
> const(HashMap!(K, V)).keys.front -> const(K)
> immutable(HashMap!(K, V)).keys.front -> immutable(K)
>
> I have encounted some difficulty in trying to write a range which does
> this.
'this' template parameters is useful in some cases. Although the 'this'
parameters are not actually referenced in the following programs they do
templatize the member function with the type of the current object.
This is a simple test that demonstrates that the mutability of the
object is transferred to the front of a range that it returns:
import std.algorithm;
struct S
{
int[5] s;
auto opSlice(this This)()
{
return s[].filter!(a => a % 2);
}
}
void main()
{
auto s = S();
auto r = s[];
static assert (is (typeof(r.front) == int));
auto sc = const(S)();
auto rc = sc[];
static assert (is (typeof(rc.front) == const(int)));
auto si = immutable(S)();
auto ri = si[];
static assert (is (typeof(ri.front) == immutable(int)));
}
The following is closer to your example (but don't pay attention to the
"hash map" implementation :p) :
import std.stdio;
import std.algorithm;
import std.array;
import std.exception;
// This can be sophisticated as well
struct Keys(Range)
{
Range range;
bool empty() const @property
{
return range.empty;
}
auto front() @property
{
return range.front;
}
void popFront()
{
range.popFront();
}
}
auto makeKeyRange(Range)(Range range)
{
return Keys!Range(range);
}
struct HashMap(K, V)
{
// Stupid implementation
K[] keys_;
V[] values_;
this(K key, V value) immutable
{
K[] makeKeysInit()
{
K[] keysInit;
keysInit ~= key;
return keysInit;
}
K[] localKeys = makeKeysInit();
keys_ = localKeys.assumeUnique;
}
auto keys(this This)()
{
return makeKeyRange(keys_);
}
}
void main()
{
// Some test types
alias K = int[];
alias V = double[];
alias HM = HashMap!(K, V);
{
auto hm = HM([ 1, 2 ], [ 1.1, 2.2 ]);
auto r = hm.keys;
static assert (is (typeof(r.front) == int[]));
}
{
auto hm = const(HM)([ 1, 2 ], [ 1.1, 2.2 ]);
auto r = hm.keys;
static assert (is (typeof(r.front) == const(int[])));
}
{
auto hm = immutable(HM)([ 1, 2 ], [ 1.1, 2.2 ]);
auto r = hm.keys;
static assert (is (typeof(r.front) == immutable(int[])));
}
}
Ali
More information about the Digitalmars-d-learn
mailing list