TDPL goes out for preliminary review
Michel Fortin
michel.fortin at michelf.com
Fri Dec 18 05:47:27 PST 2009
On 2009-12-17 23:38:58 -0500, Graham St Jack
<Graham.StJack at internode.on.net> said:
> Immutable or const objects are a real pain because I can't have a mutable
> reference to them. Rebindable doesn't seem to work, and I haven't been
> able to make a version that works well enough.
In my observation, just like the most useful string type is defined as
immutable(char)[] and thus is rebindable, most of the immutable objects
I need also need to be rebindable. Rebindable being the most needed
case, it means that I almost always need to write Rebindable!(immutable
Object) for my immutable or const objects, which is a pain.
I've been wondering yesterday if being rebindable shouldn't just be the
default for objects. The rule would be that reference types are
rebindable unless marked with final. So you would have:
const(Object) o1; // rebindable
const(final Object) o2; // not rebindable
immutable(Object) o3; // rebindable
immutable(final Object) o4; // not rebindable
Final would have no effect on non-reference types (anything but classes
and interfaces). I can see how it isn't necessarily coherent with the
rest of the const system for value types, but reference types are
different from value types too.
In essence, I just want the most frequently used type (a rebindable
object) to be easier to write than Rebindable!(immutable Object), so
I'm open to other ideas too.
As for a Rebindable that works, I've made one. Unfortunately, use of
alias this is broken because of this bug
<http://d.puremagic.com/issues/show_bug.cgi?id=3626>, so for now you
need to always use the "get" parameter for comparing to null and other
things that don't start with a dot.
private template Rebindable(T) if (is(T == class) || isArray!(T))
{
static if (!is(T X == const(U), U) && !is(T X == immutable(U), U))
{
alias T Rebindable;
}
else static if (isArray!(T))
{
alias const(ElementType!(T))[] Rebindable;
}
else
{
struct Rebindable
{
private U stripped;
void opAssign(T another)
{
stripped = cast(U) another;
}
this(T value) {
this = value;
}
T get() const {
return cast(T)stripped;
}
T opDot() const {
return get;
}
}
}
}
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list