const confusion
Witold Baryluk
baryluk at smp.if.uj.edu.pl
Tue Jun 23 06:41:52 PDT 2009
Dnia 2009-06-01, pon o godzinie 16:44 -0400, Steven Schveighoffer pisze:
> On Mon, 01 Jun 2009 16:01:04 -0400, Witold Baryluk
> <baryluk at smp.if.uj.edu.pl> wrote:
>
> > Dnia 2009-05-31, nie o godzinie 15:36 -0400, Jarrett Billingsley pisze:
> >> On Sun, May 31, 2009 at 3:26 PM, Witold Baryluk
> >> <baryluk at smp.if.uj.edu.pl> wrote:
> >> >
> >> > Horrible.
> >> >
> >> > How to ensure constness of data, and still have possibility of
> >> changing references of local variables?
> >>
> >> Rebindable.
> >>
> >> http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable
> >
> > Thanks. I was already thinking about implementing something like this.
> > It is very thin, and probably doesn't eat even single byte more than
> > original reference.
> >
> > So generally we need to cheat: union with const and non-const version +
> > opAssign/opDot, and some hidden casts. If everybody is doing this, why
> > not.
> >
> > Only one problem is that i need to make some wrappers for it:
> >
> > alias Rebindable!(C) CC;
> >
> >
> > first try:
> >
> > auto c1 = CC(new C(1));
> > auto c2 = CC(new C(2, c1)); // oops doesn't work
> > c2 = c2.b();
> >
> > second try:
> >
> > auto c1 = CC(new C(1));
> > auto c2 = CC(new C(2, c1.opDot())); // ok, works
> > c2 = c2.b();
> >
> >
> > define some function on original data:
> >
> > int something(in C c) {
> > return c.a;
> > }
> >
> > something(c2); // oops, doesn't work
> >
> > something(c2.opDot()); // ok, works
> >
> >
> >
> > So generally now i need to overload all my functions to support also
> > Rebindable!(C), where I will unwrap object and call original function?
> > The same with constructors.
> >
> > Can't be this done more simpler?
> >
> > As I remember there was something like opCast (for explicit casts)?
> > Maybe Rebindable should have it casting to original type (with const)?
> >
>
> You are running into limitations that are planned to be fixed.
>
> For example, rebindable probably shouldn't use opDot anymore... it should
> use alias this.
>
> With opDot, you don't have implicit casting back to the original type.
> But alias this provides that, not sure if aliasing a union member has been
> tested...
>
> Also, I believe Rebindable!(const C) is what you really want (I've argued
> in the past that Rebindable should just assume that it's type should be
> const). Rebindable!(T) is just an alias to T if T is not const, which is
> IMO absolutely useless.
>
> Another thing I just noticed, which probably should be fixed, there is an
> alias for get which gets the original item. get's a pretty common member
> name, I don't think it should be overridden by Rebindable.
>
> In fact, I think rebindable needs almost a rewrite with the recent
> developments of D2.
>
> The goal of Rebindable is to transparently implement the sort of
> "tail-const" behavior you want without any of the pain you are currently
> experiencing. If it doesn't work seamlessly (except for where you wish to
> explicitly define "this is a rebindable reference"), then it's not
> finished.
>
> Andrei?
>
I have curently something like this in my implementation of rebindable.
//alias Rebindable!(const C) CC;
// todo: opAssign(Rebindable!(T)) is missing so c4 = c3
// todo: T opCast() is missing for explicit cast(T)
// todo: opdot needs const
// because of this here is own Rebindable
template RBMixin(T, RetT) {
static if (is(T X == const(U), U) || is(T X == invariant(U), U)) {
private union {
T original;
U stripped;
}
RetT opAssign(T another) {
stripped = cast(U)another;
return this;
}
RetT opAssign(RetT another) {
stripped = another.stripped;
return this;
}
static RetT opCall(T initializer) {
//return RetT(initializer);
RetT result;
result = initializer;
return result;
}
T opDot() const {
return original;
}
static if (!is(T.opCast)) {
T opCast() {
return original;
}
}
}
}
template RB(T) {
static if (!is(T X == const(U), U) && !is(T X == invariant(U), U)) {
alias T RB;
} else {
struct RB {
mixin RBMixin!(T, RB);
alias original get; // legacy get
}
}
}
Then i can just use RB!(const!(mytype)), or mixin it into own struct.
I think i will rewrite it to use "alias this", and remove some
other limitation
What you think?
> -Steve
More information about the Digitalmars-d-learn
mailing list